--- phase: 01-setup plan: 01 type: execute autonomous: true status: complete completed: 2026-03-15 --- ## Goal Bootstrap the full TapTrack Hub project: Docker Compose stack, complete database schema, FastAPI backend skeleton with all routers and Celery tasks, Vue 3 frontend skeleton with all page stubs, PAUL state/roadmap files. ## What Was Built ### Infrastructure - Docker Compose: backend (gunicorn+uvicorn), celery worker, celery beat, frontend (vite+nginx), PostgreSQL 15, Redis 7, nginx reverse proxy (port 8080) - backend/Dockerfile, frontend/Dockerfile, nginx/nginx.conf ### Backend - app/database.py — async SQLAlchemy engine + Base - app/config.py — Settings (env vars: DB, Redis, SMTP, Semaphore, JWT) - app/worker.py — Celery app + beat schedule (5 tasks) - app/auth/ — password hashing (bcrypt), JWT encode/decode, FastAPI dependencies (get_current_user, require_super_admin, require_school_admin) ### Database Models (8 tables) - hub_users (id, email, full_name, hashed_password, role, school_id, is_active) - schools (id, name, slug, address, tier, status, sms_credits, sms_sender_name, ...) - licenses (id, school_id, key, status, tier, expires_at, last_validated_at, last_seen_ip) - sms_jobs (id, school_id, recipient_phone, message, sender_name, status, retry_count) - sms_credit_ledger (id, school_id, tx_type, amount, balance_after, description) - invoices + invoice_line_items (full billing schema) - school_subscriptions (monthly_fee, sms_cost_per_message, cycle, next_billing_date) - support_tickets + ticket_replies (subject, body, category, status, priority, is_internal) - audit_logs (actor, action, entity, detail, ip_address) - announcements (title, body, is_active, expires_at) ### Routers (11) - auth: POST /login, GET /me, PUT /me/password - schools: CRUD + POST /{id}/credits (SMS top-up) - licenses: list, update, revoke, POST /validate (for on-prem) - sms: POST /submit (on-prem), GET /jobs, GET /credits/{school_id} - billing: invoices CRUD + send-email, subscriptions upsert - tickets: CRUD + replies - users: CRUD (super admin) - dashboard: GET /summary (KPIs) - school_portal: GET /portal/overview (school-scoped) - announcements: CRUD - sync: POST /sync/poll (on-prem 30s poll) ### Celery Tasks (6) - sms.process_queue — send pending jobs via Semaphore, deduct credits, log ledger - sms.send_low_credit_alert — email school when balance < threshold - billing.generate_monthly_invoices — create draft invoices on 1st of month - billing.send_invoice_email — send invoice to billing contact - billing.check_overdue — mark unpaid invoices as overdue daily - license.check_expiry — email expiry warnings at 30/14/7 days - reports.send_monthly_reports — email report stub to all active schools ### Services - app/services/email.py — SMTP send_email helper ### Seed Script - backend/seed.py — creates default super admin: admin@taptrack.io / admin123! ### Frontend (Vue 3 + Vite + Tailwind + Pinia) - router: super admin routes (/, /dashboard, /schools, /licenses, /sms, /billing, /tickets, /users, /announcements) + portal routes (/portal, /portal/billing, /portal/sms, /portal/tickets, /portal/profile) - stores/auth.ts — Pinia auth store with localStorage persistence - lib/api.ts — full axios client for all endpoints - composables/useToast.ts — toast notification system - layouts: AppLayout (super admin), PortalLayout (school), AuthLayout (login) - components: AppSidebar, PortalSidebar, SidebarItem, KpiCard, StatusBadge, ToastStack - pages: LoginPage, DashboardPage, SchoolsPage, SchoolDetailPage, LicensesPage, SmsPage, BillingPage, TicketsPage, TicketDetailPage, UsersPage, AnnouncementsPage, NotFoundPage - portal pages: PortalOverviewPage, PortalBillingPage, PortalSmsPage, PortalTicketsPage, PortalProfilePage ## Acceptance Criteria (All Met) - [x] Docker Compose starts cleanly (backend, celery, frontend, db, redis, nginx) - [x] GET /api/health returns {"status":"ok"} - [x] Database tables created on startup via SQLAlchemy create_all - [x] Super admin seed script creates admin account - [x] Frontend builds and serves on port 8080 - [x] Login page renders; JWT auth flow works - [x] All 15 PAUL phase directories created