- Reorganized admin settings into tabbed interface (General, Security, Payment Methods) - Vertical tabs on desktop, horizontal scrollable on mobile - Moved Payment Methods from separate menu to Settings tab - Fixed admin profile reuse and dashboard blocking - Fixed maintenance mode guard to use AppConfig model - Added admin auto-redirect after login (admins → /admin, users → /) - Reorganized documentation into docs/ folder structure - Created comprehensive README and documentation index - Added PWA and Web Push notifications to to-do list
13 KiB
Admin Features TODO List
🔴 HIGH PRIORITY - Backend Implementation Required
1. Suspended User Implementation
Status: ⚠️ UI Only - Backend Logic Missing
Current State:
- ✅ UI: Suspend/Unsuspend buttons in Admin Users page
- ✅ API: Endpoints exist (
/api/admin/users/:id/suspend,/api/admin/users/:id/unsuspend) - ❌ Missing: Middleware to block suspended users from accessing the app
Required Implementation:
// apps/api/src/auth/auth.guard.ts
// Add check for suspendedAt field
if (user.suspendedAt) {
throw new UnauthorizedException('Your account has been suspended. Reason: ' + user.suspendedReason);
}
Tasks:
- Add suspended user check in AuthGuard
- Return proper error message with suspension reason
- Test: Suspended user cannot login
- Test: Suspended user's active sessions are invalidated
- Frontend: Show suspension message on login attempt
2. Pro Features Implementation
Status: ⚠️ UI Only - No Pro Features Defined
Current State:
- ✅ UI: Grant Pro Access dialog in Admin Users page
- ✅ API: Endpoint exists (
/api/admin/users/:id/grant-pro) - ✅ Database: Subscription model exists
- ❌ Missing: Actual pro features and restrictions
Required Implementation:
A. Define Pro Features:
// Pro Features List:
1. Unlimited wallets (Free: max 5)
2. Unlimited transactions (Free: max 100/month)
3. Advanced analytics & reports
4. Export data (CSV, PDF)
5. Multiple currencies
6. Recurring transactions
7. Budget planning
8. Custom categories (Free: limited to default)
9. API access
10. Priority support
B. Create Pro Guard:
// apps/api/src/subscription/guards/pro.guard.ts
@Injectable()
export class ProGuard implements CanActivate {
async canActivate(context: ExecutionContext): Promise<boolean> {
const request = context.switchToHttp().getRequest();
const user = request.user;
// Check if user has active pro subscription
const subscription = await this.prisma.subscription.findUnique({
where: { userId: user.id },
});
if (!subscription || subscription.status !== 'active') {
throw new ForbiddenException('This feature requires Pro subscription');
}
return true;
}
}
C. Apply Restrictions:
// Example: Limit wallets for free users
// apps/api/src/wallets/wallets.service.ts
async create(userId: string, data: CreateWalletDto) {
const subscription = await this.getSubscription(userId);
if (!subscription || subscription.status !== 'active') {
// Free user - check limits
const walletCount = await this.prisma.wallet.count({
where: { userId, deletedAt: null }
});
if (walletCount >= 5) {
throw new ForbiddenException('Free users can only create up to 5 wallets. Upgrade to Pro for unlimited wallets.');
}
}
// Create wallet...
}
Tasks:
- Define all Pro features and free limits
- Create ProGuard decorator
- Apply wallet limit (5 for free users)
- Apply transaction limit (100/month for free users)
- Add Pro badge in frontend for Pro users
- Show upgrade prompt when hitting limits
- Create pricing page
- Add "Upgrade to Pro" button in app
3. Maintenance Mode Implementation
Status: ⚠️ UI Only - Backend Logic Missing
Current State:
- ✅ UI: Toggle in Admin Settings page
- ✅ Database:
Configtable withmaintenanceModekey - ❌ Missing: Middleware to block users during maintenance
Required Implementation:
A. Create Maintenance Middleware:
// apps/api/src/common/middleware/maintenance.middleware.ts
@Injectable()
export class MaintenanceMiddleware implements NestMiddleware {
constructor(private readonly prisma: PrismaService) {}
async use(req: Request, res: Response, next: NextFunction) {
// Skip for admin users
if (req.user?.role === 'admin') {
return next();
}
// Check maintenance mode
const config = await this.prisma.config.findUnique({
where: { key: 'maintenanceMode' }
});
if (config?.value === 'true') {
throw new ServiceUnavailableException({
message: 'System is under maintenance. Please try again later.',
maintenanceMode: true
});
}
next();
}
}
B. Apply Globally:
// apps/api/src/main.ts
app.use(new MaintenanceMiddleware(prisma));
C. Frontend Handling:
// apps/web/src/App.tsx
// Show maintenance page when API returns 503
if (error.response?.status === 503 && error.response?.data?.maintenanceMode) {
return <MaintenancePage />;
}
Tasks:
- Create MaintenanceMiddleware
- Apply middleware globally (except admin routes)
- Create MaintenancePage component
- Test: Regular users blocked during maintenance
- Test: Admin users can still access
- Add maintenance message customization in settings
4. New User Registration Toggle Implementation
Status: ⚠️ UI Only - Backend Logic Missing
Current State:
- ✅ UI: Toggle in Admin Settings page
- ✅ Database:
Configtable withallowRegistrationkey - ❌ Missing: Check in registration endpoint
Required Implementation:
A. Add Check in Auth Service:
// apps/api/src/auth/auth.service.ts
async register(email: string, password: string) {
// Check if registration is allowed
const config = await this.prisma.config.findUnique({
where: { key: 'allowRegistration' }
});
if (config?.value === 'false') {
throw new ForbiddenException('New user registration is currently disabled. Please contact administrator.');
}
// Continue with registration...
}
B. Frontend Handling:
// apps/web/src/pages/Register.tsx
// Show message if registration is disabled
if (error.response?.data?.message?.includes('registration is currently disabled')) {
return (
<Alert>
<AlertTitle>Registration Disabled</AlertTitle>
<AlertDescription>
New user registration is currently disabled. Please contact the administrator.
</AlertDescription>
</Alert>
);
}
Tasks:
- Add registration check in auth.service.ts
- Update register endpoint
- Frontend: Show disabled message
- Test: Registration blocked when disabled
- Test: Admin can still create users manually
5. Email Verification Requirement Implementation
Status: ⚠️ UI Only - Backend Logic Missing
Current State:
- ✅ UI: Toggle in Admin Settings page
- ✅ Database:
Configtable withrequireEmailVerificationkey - ✅ Database:
User.emailVerifiedfield exists - ❌ Missing: Enforcement in AuthGuard
Required Implementation:
A. Add Check in AuthGuard:
// apps/api/src/auth/auth.guard.ts
async canActivate(context: ExecutionContext): Promise<boolean> {
// ... existing auth checks ...
// Check if email verification is required
const config = await this.prisma.config.findUnique({
where: { key: 'requireEmailVerification' }
});
if (config?.value === 'true' && !user.emailVerified) {
throw new UnauthorizedException({
message: 'Please verify your email address to continue.',
emailVerificationRequired: true,
email: user.email
});
}
return true;
}
B. Resend Verification Email:
// apps/api/src/auth/auth.controller.ts
@Post('resend-verification')
async resendVerification(@Body() body: { email: string }) {
return this.authService.resendVerificationEmail(body.email);
}
C. Frontend Handling:
// apps/web/src/components/EmailVerificationRequired.tsx
// Show verification required page with resend button
Tasks:
- Add email verification check in AuthGuard
- Create resend verification endpoint
- Create EmailVerificationRequired component
- Test: Unverified users blocked when required
- Test: Resend verification email works
- Add email verification link in emails
6. Manual Payment Verification Implementation
Status: ⚠️ UI Only - Backend Logic Missing
Current State:
- ✅ UI: Toggle in Admin Settings page
- ✅ Database:
Configtable withrequireManualPaymentVerificationkey - ✅ Database:
Payment.statusfield exists - ❌ Missing: Payment verification workflow
Required Implementation:
A. Payment Verification Endpoint:
// apps/api/src/admin/admin-payments.controller.ts
@Post(':id/verify')
async verifyPayment(
@Param('id') id: string,
@Body() body: { approved: boolean; notes?: string }
) {
return this.service.verifyPayment(id, body.approved, body.notes);
}
B. Payment Verification Service:
// apps/api/src/admin/admin-payments.service.ts
async verifyPayment(paymentId: string, approved: boolean, notes?: string) {
const payment = await this.prisma.payment.findUnique({
where: { id: paymentId },
include: { user: true }
});
if (approved) {
// Approve payment
await this.prisma.payment.update({
where: { id: paymentId },
data: {
status: 'completed',
verifiedAt: new Date(),
verificationNotes: notes
}
});
// Activate subscription
await this.activateSubscription(payment.userId, payment.planId);
// Send confirmation email
await this.emailService.sendPaymentApproved(payment.user.email);
} else {
// Reject payment
await this.prisma.payment.update({
where: { id: paymentId },
data: {
status: 'failed',
verifiedAt: new Date(),
verificationNotes: notes
}
});
// Send rejection email
await this.emailService.sendPaymentRejected(payment.user.email, notes);
}
}
C. Payment Status Check:
// apps/api/src/payments/payments.service.ts
async create(userId: string, data: CreatePaymentDto) {
const config = await this.prisma.config.findUnique({
where: { key: 'requireManualPaymentVerification' }
});
const status = config?.value === 'true' ? 'pending' : 'completed';
const payment = await this.prisma.payment.create({
data: {
...data,
userId,
status
}
});
if (status === 'completed') {
// Auto-activate subscription
await this.activateSubscription(userId, data.planId);
} else {
// Notify admin of pending payment
await this.notifyAdminNewPayment(payment);
}
return payment;
}
D. Admin UI for Verification:
// apps/web/src/components/admin/pages/AdminPayments.tsx
// Add Verify/Reject buttons for pending payments
<Button onClick={() => openVerifyDialog(payment.id)}>
Verify Payment
</Button>
Tasks:
- Create payment verification endpoints
- Add verification logic in service
- Create admin verification UI
- Send email notifications (approved/rejected)
- Test: Manual verification workflow
- Test: Auto-approval when disabled
- Add payment receipt upload
🟡 MEDIUM PRIORITY - UI Translation to English
Admin Dashboard Pages to Translate:
1. Dashboard (AdminDashboard.tsx)
Current: Mixed Indonesian/English Tasks:
- Convert all headings to English
- Convert all labels to English
- Convert all button text to English
- Convert all chart labels to English
- Convert all toast messages to English
2. Plans (AdminPlans.tsx)
Current: Mixed Indonesian/English Tasks:
- Convert page title and description
- Convert form labels
- Convert button text
- Convert table headers
- Convert dialog text
- Convert toast messages
3. Payment Methods (AdminPaymentMethods.tsx)
Current: Mixed Indonesian/English Tasks:
- Convert page title and description
- Convert form labels
- Convert button text
- Convert table headers
- Convert dialog text
- Convert toast messages
4. Payments (AdminPayments.tsx)
Current: Mixed Indonesian/English Tasks:
- Convert page title and description
- Convert filter labels
- Convert table headers
- Convert status badges
- Convert dialog text
- Convert toast messages
5. Settings (AdminSettings.tsx)
Current: Mixed Indonesian/English Tasks:
- Convert page title and description
- Convert section titles
- Convert toggle labels
- Convert button text
- Convert toast messages
- Convert help text
📋 Summary
Backend Implementation Priority:
- Suspended User - Critical security feature
- Email Verification - Important for user management
- Maintenance Mode - Important for system updates
- Registration Toggle - Important for user management
- Pro Features - Business logic (most complex)
- Manual Payment Verification - Business logic
Frontend Translation Priority:
- Dashboard - Most visible page
- Settings - Admin configuration
- Payments - Business critical
- Plans - Business critical
- Payment Methods - Business critical
Estimated Time:
- Backend Implementation: 3-5 days
- Frontend Translation: 2-3 hours
- Testing: 1-2 days
Total: ~1 week for complete implementation