app: refactored and generalised