Skip to content

Latest commit

 

History

8 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Quacksters

Mobile onboarding companion for Quackteow Group staff, based on QT-HR-OPS-001 (30 · 60 · 90 Day Integration Programme).

Built with React, TypeScript, Tailwind CSS, and Capacitor for Android and iOS.

Features

  • Interactive roadmap dashboard with phase timeline
  • Role-filtered checklists (Cook, Cashier, Supervisor)
  • Self-registration with HR approval workflow
  • Web admin console at /admin (registrations, users, hire progress, programme CMS)
  • Live programme editor backed by Supabase (tasks, resources, milestones, outlets)
  • Role-based admin navigation (admin, supervisor, GM, HR Ops, EXCO)
  • Progress synced to Supabase (with local offline cache on device)
  • Resource hub with SOP links
  • Milestone reminders (Day 7, 15, 30, 45, 60, 90)
  • Native Android and iOS shells with splash screen, status bar, and haptics

Supabase setup

  1. Create a dedicated Supabase project for Quacksters.
  2. Apply migrations:
# Using Supabase CLI (recommended)
supabase db push

# Or run each file in supabase/migrations/ via the SQL editor, in order.

Key migrations:

Migration Purpose
20260519000000_quacksters_auth_schema.sql Auth, profiles, hire progress
20260519140000_programme_content.sql Programme tables + get_programme()
20260519140100_programme_seed.sql Seed from QT-HR-OPS-001 mock data
20260519140200_programme_admin_rpcs.sql Admin write RPCs for programme CMS
20260519150000_outlets_and_audit.sql Outlets config + admin audit log
20260520100000_audit_hr_actions_reorders_password_reset.sql HR auditing, user update audit/password flag, programme list reorders
20260520100500_fix_admin_list_users_signature.sql Drops and recreates admin_list_users (new column; PG forbids REPLACE on row-type change)
20260520103000_audit_log_filters_complete_password_change.sql Audit log RPC: filters + offset paging; complete_password_change() for audited self‑service password clears

After pulling this migration, run supabase db push on your project (staging first), then smoke-test Admin → Audit (filters, load more, CSV) and forced password reset → new password → profile no longer flagged.

Regenerate the programme seed after editing mock data:

npm run generate:programme-seed
  1. Copy environment variables:
cp .env.example .env
# Set VITE_SUPABASE_URL and VITE_SUPABASE_ANON_KEY from your project settings
  1. Bootstrap the first admin (see supabase/seed.sql):

    • Create a user in Supabase Auth
    • Run the SQL update to set access_role = 'admin'
  2. In Supabase Auth settings, disable email confirmation for local dev (optional).

Without .env, the app runs in offline mode with local-only profile setup (legacy behaviour). A banner appears when programme content falls back to cached/mock data.

Auth and admin routes

Route Purpose
/register Self-register (pending HR approval)
/login Sign in
/reset-password Required password change when password_reset_required
/pending Awaiting approval / rejection status
/ Mobile onboarding app (approved hires)
/admin Admin dashboard
/admin/registrations Approve/reject queue (HR Ops, Admin)
/admin/users User and role management (Admin, HR Ops, GM)
/admin/hires/:id Hire onboarding progress detail
/admin/checklist Manager checklist (Supervisor, GM)
/admin/programme Programme CMS (Admin only)
/admin/audit Audit log (Admin + HR Ops)

Admin navigation by role

Role Nav items
admin Dashboard, Programme, Audit log, Registrations, Users
supervisor Dashboard, My checklist
gm Dashboard, My checklist, Users
hr_ops Dashboard, Audit log, Registrations, Users
exco Dashboard (read-only)

Access roles

Role Description
pending Registered, awaiting approval
hire New hire — mobile onboarding
supervisor Outlet supervisor (SUP)
gm General Manager
exco Executive Committee (read-only admin)
hr_ops HR Operations — registration approval
admin Full system admin

Job roles (cook, cashier, supervisor) are separate and control checklist filtering.

Quick start (web)

npm install
npm run dev

Open the URL shown in the terminal (usually http://localhost:5173).

Scripts

Command Purpose
npm run dev Local dev server
npm run build Production build
npm run lint ESLint
npm run test Vitest unit tests
npm run test:e2e Playwright smoke test (starts preview server)
./scripts/run-android.sh Clean + installDebug + launch MainActivity (needs adb device)
./scripts/run-ios.sh Sync + build for iOS Simulator + open Xcode (needs full Xcode)
npm run cap:ios Build, sync, and open the iOS project in Xcode
npm run generate:programme-seed Regenerate programme seed SQL from mock data

Deploy web app (GitHub Pages)

The workflow .github/workflows/deploy-pages.yml builds the Vite SPA and publishes dist/ to GitHub Pages on every push to main or master (and can be run manually via Actions → Deploy GitHub Pages → Run workflow).

This repository (project site): the live app is at https://ezzademir.github.io/Quacksters/. The app uses HashRouter, so routes look like https://ezzademir.github.io/Quacksters/#/login (not /Quacksters/login — that avoids GitHub Pages 404 on refresh and deep links).

One-time repository setup

  1. Push this repository to GitHub.
  2. Settings → Pages → Build and deployment: set Source to GitHub Actions (not “Deploy from a branch”).
  3. Settings → Secrets and variables → Actions — add VITE_SUPABASE_ANON_KEY:
    • Copy anon public from Supabase Dashboard → Project Settings → API. Use the JWT value starting with eyJ (same as local .env). Never service_role, never commit keys into git.
    • VITE_SUPABASE_URL is optional for Pages: .github/workflows/deploy-pages.yml defaults to https://oivsccsntugiprfdnypn.supabase.co. Add this secret only if the deployed site should use a different Supabase project than that URL.

Set the anon key from your machine with GitHub CLI (prompt hides input):

gh secret set VITE_SUPABASE_ANON_KEY

If VITE_SUPABASE_ANON_KEY is missing, the Pages build still succeeds but the site runs without Supabase (offline behaviour); the workflow prints a warning.

Confirm the live site: open Sign in. Under the form, Backend: should match Project URL in the dashboard (oivsccsntugiprfdnypn.supabase.co for the default URL).

If every login shows “does not match our records”: the build is almost certainly using a bad VITE_SUPABASE_ANON_KEY (GitHub Secret). Paste the anon public JWT (eyJ…) from Dashboard → API again — no wrapping quotes, no line breaks. Publishable sb_publishable_ keys often fail with password auth and RLS. After updating the secret, run Deploy GitHub Pages again and hard-refresh the site (or clear site data for github.io). The app also clears a broken local session before each sign-in attempt.

Seeing 400 (Bad Request) on …/auth/v1/token?grant_type=password in DevTools: that HTTP status is normal when GoTrue rejects a password grant (wrong password, unconfirmed email, captcha required, etc.). Open the failed request in Network → Response and read the JSON (error, error_code, msg) — that is the authoritative reason, not the status code alone.

If the URL secret and anon key secret are from different Supabase projects, the sign-in page shows an amber “Configuration issue” banner and the browser console logs [auth] details — fix secrets so both come from the same project.

Published URL

Repository type Example URL VITE_BASE_PATH in CI
Project repo owner/repo https://owner.github.io/repo/ /<repo>/
Site repo named owner.github.io https://owner.github.io/ /

Vite reads VITE_BASE_PATH at build time; local/Android builds omit it so base stays ./ for Capacitor.

Supabase redirect URLs

In the Supabase Dashboard → Authentication → URL configuration, allow the site URL (and redirect URLs) Supabase will send users to. This app uses HashRouter and password-reset emails use the SPA root as redirect_to (Supabase then appends #access_token=...&type=recovery). The app listens for PASSWORD_RECOVERY and navigates to #/recover-password.

Add explicit allowlist entries for this repo, for example:

  • https://ezzademir.github.io/Quacksters/
  • http://localhost:5173/ (local Vite dev, if testing reset mail there)

Do not rely on path-only URLs like /Quacksters/recover-password for email redirects; GitHub Pages would 404 on those without hash routing.

After reset, users complete the flow at .../Quacksters/#/recover-password inside the SPA.

APK vs Pages

Installing Android release APK (Release build) bundles web assets from npm run cap:sync at build time. Updating Pages does not update installed APKs unless you add a separate live-update mechanism.

Ship app-release.apk with GitHub Releases

After building android/app/build/outputs/apk/release/app-release.apk locally, open GitHub → Releases → Draft a new release, attach the APK, and publish. Use a private repository if the binary must stay internal-only.

Automating signed APK builds in Actions requires storing keystore material as encrypted secrets—left as a future enhancement unless your team standardizes it.

Android development

Step-by-step from clone to app-debug.apk on an emulator or USB device: docs/android-apk-walkthrough.md. With a device connected (adb devices), ./scripts/run-android.sh performs clean + install + launch.

Prerequisites

  • Android Studio with SDK installed
  • JDK (bundled with Android Studio)

Environment

source scripts/android-env.sh

Default SDK path: ~/Library/Android/sdk

Sync web build to Android

npm run cap:sync

Open in Android Studio

npm run cap:android

Run on emulator or device

source scripts/android-env.sh
cd android && ./gradlew installDebug
adb shell am start -n com.quackteow.onboarding/.MainActivity

iOS development

Step-by-step from clone to running on simulator or device: docs/ios-walkthrough.md. With full Xcode installed, ./scripts/run-ios.sh syncs web assets, builds for the default simulator, and opens the project.

Prerequisites

  • Xcode from the Mac App Store (not Command Line Tools alone)
  • Apple ID for signing (free account works for device testing)

Point the active developer tools at Xcode:

sudo xcode-select -s /Applications/Xcode.app/Contents/Developer

Sync web build to iOS

npm run cap:sync

Open in Xcode

npm run cap:ios

Run on simulator or device

  1. Open ios/App/App.xcodeproj in Xcode (or use npm run cap:ios).
  2. Select a simulator or connected iPhone.
  3. Under Signing & Capabilities, choose your Team.
  4. Press Run (▶).

For TestFlight or App Store distribution, use Product → Archive in Xcode.

Release build

  1. Generate a signing keystore:
chmod +x scripts/generate-keystore.sh
./scripts/generate-keystore.sh
  1. Copy and edit signing config:
cp android/keystore.properties.example android/keystore.properties
# Update passwords in keystore.properties
  1. Build release APK:
npm run cap:release

Output: android/app/build/outputs/apk/release/app-release.apk

For Play Store, use ./gradlew bundleRelease to produce an AAB.

App identity

Field Value
App name Quacksters
Package ID com.quackteow.onboarding
Version 1.0.0 (Android versionCode / iOS build 2)

Project structure

src/
├── components/
│   ├── admin/      # Web admin console + programme editor
│   ├── auth/       # Login, register, route guards
│   ├── dashboard/  # Mobile dashboard
│   ├── onboarding/ # Welcome / hire confirmation
│   └── ...
├── context/        # Auth, outlets, programme, onboarding state
├── data/           # Fallback roadmap data from QT-HR-OPS-001
├── lib/            # Supabase, permissions, programme API, storage
└── types/          # TypeScript interfaces
supabase/
├── migrations/     # Database schema + RLS + programme RPCs
└── seed.sql        # Bootstrap admin instructions
android/            # Capacitor Android project
ios/                # Capacitor iOS project
scripts/            # android-env.sh, run-android.sh, run-ios.sh, generate-keystore.sh, generate-programme-seed.mjs

CI

GitHub Actions runs ESLint, Vitest, production build, and a Playwright smoke test on push/PR to main or master.

A separate workflow Deploy GitHub Pages (see Deploy web app (GitHub Pages)) publishes the SPA to Pages on pushes to main/master when Pages is enabled.

When developing locally: npx playwright install chromium once if npm run test:e2e fails to find browsers.

Confidentiality

Internal use only. Aligned to QT-SOP-OPS-002 v3.0.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages