Skip to content

cikeyz/prepflow

Repository files navigation

PrepFlow

Thai Joint PH

Thai Joint PH ordering, payment verification, and kitchen prep automation.
Responsive customer web app, seller/admin dashboard, PHP JSON API, and Capacitor Android APK.

Live Web  ·  Admin Dashboard  ·  API Health  ·  Architecture  ·  Deployment  ·  Diagrams

PHP 8.2 Laravel 12 React 18 TypeScript Bun workspace Capacitor Android Render Vercel TiDB License MIT

Contents

Overview

PrepFlow replaces Thai Joint PH's scattered Facebook/Instagram DM ordering workflow with a single system for:

  • customer menu browsing, cart, checkout, receipt upload, and order tracking
  • seller payment verification with receipt screenshot + OCR text
  • menu CRUD with recipe ingredient mapping
  • automatic prep/procurement aggregation from confirmed orders
  • fulfillment settings, shipping tiers, batch capacity, analytics, and courier-link updates
  • Android packaging through Capacitor with native camera capture

Payment is intentionally receipt upload + seller verification. There is no PayMongo, GCash API, bank API, card processing, or courier dispatch API. That keeps payment scope simple and avoids PCI territory.

Live Deployment

Surface URL Notes
Customer web https://prepflow-vercel-static.vercel.app Current Vercel static app URL
Admin dashboard https://prepflow-vercel-static.vercel.app/admin Login with seeded admin account
Legacy/stale Vercel URL https://thaijoint-prepflow.vercel.app Older alias; do not use until it is reassigned to the latest deployment
Same-origin API proxy https://prepflow-vercel-static.vercel.app/api/menu Vercel rewrite to Render; should return JSON, not index.html
Laravel API https://prepflow-api.onrender.com Render Docker service; cold starts are expected on free tier
Public API health https://prepflow-api.onrender.com/api/menu Returns seeded menu JSON
Deployment runbook docs/deployment/free-tier.md Render + TiDB + Vercel setup

Demo Accounts

Role Email Password
Admin admin@thaijoint.ph prepflow123
Customer maria@example.com prepflow123

Do not reuse these credentials for any real deployment. They are seeded demo accounts only.

Operations Dashboards

Use these dashboards when something breaks in production. Do not put secrets in issues, screenshots, docs, or memory; only record env variable names and non-secret service names.

Dashboard Project / service Use it for Known-good checks
GitHub cikeyz/prepflow PR history, commits, branch state, source of render.yaml and vercel.json main must include PR #24 or newer, same-origin Vercel API proxy
Vercel cikeyzs-projects/prepflow-vercel-static Static web deploys, aliases, VITE_API_URL, build logs prepflow-vercel-static.vercel.app points to latest production deploy; VITE_API_URL=/api
Render prepflow-api Laravel Docker API logs, env vars, deploys, migrations, cold-start diagnosis Health check path /api/menu; Docker image installs PHP PDO MySQL + Tesseract
TiDB Cloud PrepFlow Starter, AWS Singapore MySQL-compatible production database, connection/firewall/metrics Port 4000; Render uses SSL CA bundle via MYSQL_ATTR_SSL_CA
Cloudinary PrepFlow image cloud Menu photos, payment proofs, payment-method QR images, OCR input URLs API stores Cloudinary URLs only; no data URLs in DB
Brevo Transactional email SMTP credentials, sender verification, delivery/open logs Render uses SMTP on port 2525; domain auth still needs an owned domain
Android Studio Local apps/mobile/android project Debug APK build/install/logcat bun run build:mobile targets deployed Render API for production APK testing

Provider dashboard details and recovery steps live in docs/deployment/free-tier.md. The current rubric audit is docs/planning/submission-readiness-2026-06-29.md; older planning logs remain historical context.

Current Production Evidence

  • main is synced with origin/main at 734c61c fix: polish admin prep controls (#51).
  • The live web app is served from https://prepflow-vercel-static.vercel.app. The older https://thaijoint-prepflow.vercel.app alias has served stale bundles and should not be used until it is reassigned to the latest Vercel deployment.
  • Vercel serves the web app from https://prepflow-vercel-static.vercel.app and proxies /api/* to Render. The browser bundle should use /api, not the direct Render URL, so login cookies are same-origin on the web dashboard.
  • Latest verified gate: bun run build, bun run build:mobile, Android .\gradlew.bat assembleDebug, PHP tests 122 passed (429 assertions), and vendor\bin\pint --test.
  • Latest debug APK: apps/mobile/android/app/build/outputs/apk/debug/app-debug.apk (SHA-256 13B8A6D256766CFC39BF363C49BEECAC6DEF41B3D4FE5290F339CB5891545EED).
  • Free web domains are Vercel subdomains. A branded sender/domain still requires a domain you control so Brevo can authenticate SPF/DKIM/DMARC.
  • OCR was tested locally and through the deployed API using a GCash receipt screenshot. Render uploaded the receipt to Cloudinary, ran Tesseract, stored proof_ocr_text, and parsed:
{
  "amount_paid": "674.00",
  "reference_number": "9042061574023",
  "order_date": "Jun 20, 2026",
  "order_time": "5:40 PM"
}

A live demo payment-uploaded order exists in the admin queue as evidence of the deployed OCR path.

Product Screenshots

The screenshots below are committed evidence for the rubric's user documentation, responsive UI, admin workflow, and mobile-app sections.

Customer web landing Mobile menu
Customer web landing page Mobile menu with live dish photos
Admin dashboard Menu management COD order detail
Admin dashboard with slim sidebar and even stats Admin menu management COD order detail without payment proof panel

Rubric Coverage

Rubric section Evidence in this repo
I. Documentation & planning Proposal/background in docs/planning/, architecture in docs/ARCHITECTURE.md, ERD/DFD/C4/flowcharts in docs/SYSTEM-DIAGRAMS.md, screenshots in docs/screenshots/, and this README.
II. Responsive website design Vite/React/Tailwind app, mobile/tablet/desktop layouts, committed desktop and mobile screenshots, and same-origin Vercel deployment.
III. PHP session management Laravel session auth with regeneration, role middleware, timeout/config hardening, and feature tests.
IV. AJAX implementation Centralized JSON API wrapper in apps/web/src/lib/api.ts, TanStack Query mutations, loading/error UI, and no full-page reloads for data operations.
V. JSON data handling Explicit PHP json_encode response trait, Content-Type: application/json, JSON parsing in the React API wrapper, zod/client validation, and Laravel validation.
VI. Database integration Normalized MySQL-compatible schema, migrations, foreign keys, indexes, CRUD, transactions, and procurement aggregation view.
VII. Mobile application Capacitor Android APK, deployed API connectivity, native camera/gallery receipt capture, local notifications, and FCM token plumbing.
VIII. Presentation & defense docs/planning/presentation-script.md, docs/planning/submission-readiness-2026-06-29.md, screenshots, diagrams, and verification gates.

System Visuals

Deployment Topology

flowchart LR
  Customer["Customer Browser"] --> Web["Vercel Static React App"]
  Admin["Seller/Admin Browser"] --> Web
  Mobile["Capacitor Android APK"] --> API
  Web -->|"JSON + session cookies"| API["Render Docker API<br/>PHP 8.2 + Laravel 12"]
  API -->|"PDO MySQL + SSL"| DB[("TiDB Cloud Starter<br/>MySQL-compatible")]
  API -->|"signed image uploads"| Cloudinary["Cloudinary<br/>menu photos + payment proofs"]
  API -->|"receipt OCR"| Tesseract["Tesseract OCR<br/>in Docker image"]
  API -->|"log driver by default"| Mail["Transactional Email"]
Loading

Order + Prep Flow

sequenceDiagram
  participant C as Customer
  participant W as React / Capacitor UI
  participant A as Laravel API
  participant D as TiDB / MySQL
  participant S as Seller Admin

  C->>W: Browse menu and add cart items
  W->>A: GET /api/menu, /api/batches
  A->>D: Read available menu + capacity
  C->>W: Select fulfillment + payment method
  W->>A: POST /api/orders
  A->>D: Transaction: lock batch, validate cutoff/capacity, insert order/items
  C->>W: Upload GCash/bank receipt screenshot
  W->>A: POST /api/orders/{id}/payment-proof
  A->>D: Store proof URL, OCR text, status payment_uploaded
  S->>W: Open payment verification queue
  W->>A: GET /api/admin/orders?status=payment_uploaded
  S->>A: Verify payment
  A->>D: Transaction: status confirmed + audit log
  S->>W: Open Prep & Procurement
  W->>A: GET /api/admin/prep?date=...
  A->>D: Aggregate recipe_ingredients x order_items
Loading

Stack

Layer Technology Why
Backend PHP 8.2, Laravel 12, PDO/MySQL Keeps rubric-visible sessions, json_encode, and prepared statements while retaining migrations/tests
Database TiDB Cloud Starter locally-compatible MySQL Free MySQL-compatible production DB with SSL
Web Vite, React 18, TypeScript, Tailwind, TanStack Query SPA for customer/admin workflows with JSON API calls
Shared contract packages/shared zod schemas + apps/web/src/types.ts Client/server DTO validation and schema mirror discipline
Mobile Capacitor 6 Android Wraps the React build and uses native Camera for receipt capture
Images Cloudinary Stores menu images, payment proof screenshots, and QR images
OCR Tesseract in Render Docker; Cloudinary OCR if available Best-effort receipt text extraction; never auto-approves payments
Email Laravel Mailables, Brevo SMTP in production, log driver by default locally Order confirmation/courier-link email without committing SMTP secrets
Deployment Render API, Vercel web, TiDB DB Free-tier deployment without card-gated Koyeb

Feature Map

Customer

  • Landing/menu highlights from live menu_items.
  • Menu browse, search, availability filter, image rendering, smart favorites/reorder.
  • Cart, checkout, fulfillment/date picker, batch capacity meter, shipping tier fee display.
  • Seller-configured payment method display with QR/account details.
  • Receipt screenshot capture via shared capturePhoto() and payment-proof upload.
  • Orders list, order tracker, courier-link card, and post-checkout success screen.
  • Session login/register with role routing.

Admin

  • Dashboard: revenue, average order, customers, repeat rate, status counts, revenue by day, top sellers, peak days.
  • Menu Manager: CRUD, Cloudinary image upload, recipe ingredient mapping, availability rules.
  • Orders: status filters, payment verification queue, screenshot + expected total + OCR text/hints, verify/reject, bulk status updates.
  • Order Detail: full customer/order/items/payment proof/OCR/audit trail/status controls.
  • Prep & Procurement: confirmed dish counts + ingredient totals grouped by fulfillment date.
  • Settings: payment methods and QR images, fulfillment options, shipping tiers, batches/cutoffs.

Repository Layout

PrepFlow/
├── api/                  # Laravel API, migrations, PHPUnit tests, Docker runtime
├── apps/
│   ├── web/              # Vite React customer/admin SPA
│   └── mobile/           # Capacitor Android shell; generated android/ is ignored
├── db/                   # Canonical MySQL schema reference
├── docs/                 # Architecture, ERD, DFD, deployment, planning reports
├── packages/
│   └── shared/           # zod schemas and shared TypeScript DTOs
├── tools/                # composer.phar, no global Composer required
├── DECISIONS.md          # locked product/architecture decisions
├── render.yaml           # Render Blueprint reference
└── package.json          # Bun workspace shortcuts

Local Development

Prerequisites

  • Windows + PowerShell
  • XAMPP with PHP 8.2 and MySQL/MariaDB (C:\xampp\php expected)
  • Bun 1.3+
  • Android Studio + Android SDK for APK work
  • Cloudinary account for image upload testing
  • Optional local OCR: Tesseract at C:\Program Files\Tesseract-OCR\tesseract.exe

0. Clone the Repository

git clone https://github.com/cikeyz/prepflow.git
cd prepflow

If you have SSH keys set up with GitHub, you can use the SSH URL instead: git clone git@github.com:cikeyz/prepflow.git.

1. Install Workspace Dependencies

bun install

2. Configure Backend

cd api
$env:PATH = 'C:\xampp\php;' + $env:PATH
php ..\tools\composer.phar install
Copy-Item .env.example .env
php artisan key:generate

Set local .env values. Keep .env uncommitted.

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=prepflow
DB_USERNAME=root
DB_PASSWORD=
CLOUDINARY_URL=cloudinary://<api_key>:<api_secret>@<cloud_name>
OCR_TECHNIQUE=none
TESSERACT_BIN=

For local Tesseract OCR:

OCR_TECHNIQUE=tesseract
TESSERACT_BIN=C:\Program Files\Tesseract-OCR\tesseract.exe

3. Create Local Database

Run these from the api/ directory (same as Step 2):

& 'C:\xampp\mysql\bin\mysql.exe' -u root -e "CREATE DATABASE prepflow CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;"
php artisan migrate --seed
php artisan storage:link

The storage:link command creates a symlink for locally-stored files. On Windows, this may require Developer Mode or running PowerShell as Administrator. If it fails, enable Developer Mode in Settings → Privacy & Security → For Developers.

4. Run API + Web

Terminal 1:

cd api
$env:PATH = 'C:\xampp\php;' + $env:PATH
php artisan serve --host=127.0.0.1 --port=8000

Terminal 2:

cd apps/web
bun run dev

Open http://localhost:5173.

Android / APK

Prebuilt debug APKs are on GitHub Releases (PrepFlow-debug.apk and production-API variants). Install with unknown sources allowed. These are debug builds, not Play Store packages.

Rebuild locally:

# from repo root
bun run build:mobile

cd apps/mobile/android
# Set these to match your local Android SDK and Java paths
$env:ANDROID_HOME='C:\Android\Sdk'
$env:ANDROID_SDK_ROOT='C:\Android\Sdk'
$env:JAVA_HOME='C:\Program Files\Android\Android Studio\jbr'
.\gradlew.bat assembleDebug

Debug APK output:

apps/mobile/android/app/build/outputs/apk/debug/app-debug.apk

For production APKs, the root mobile build script targets the deployed Render API:

bun run build:mobile

For emulator/local API testing, use bun run build:mobile:local; it targets http://10.0.2.2:8000/api.

More details: apps/mobile/README.md.

Deployment

The current free-tier deployment is:

PrepFlow production
├── Vercel static app
│   └── /api/* rewrite -> Render Docker Laravel API
│       ├── TiDB Cloud Starter
│       ├── Cloudinary
│       └── Tesseract OCR
└── Capacitor Android APK
    └── HTTPS JSON/session API -> Render Docker Laravel API

Required production environment variables are documented in docs/deployment/free-tier.md. Key values:

Provider Required setting
Vercel VITE_API_URL=/api or leave unset; vercel.json proxies /api/* to Render
Render APP_ENV=production, APP_DEBUG=false, APP_URL=https://prepflow-api.onrender.com
Render DB_* TiDB values, MYSQL_ATTR_SSL_CA=/etc/ssl/certs/ca-certificates.crt
Render SESSION_DRIVER=database, SESSION_SAME_SITE=none, SESSION_SECURE_COOKIE=true
Render CLOUDINARY_URL, OCR_TECHNIQUE=tesseract, TESSERACT_BIN=/usr/bin/tesseract
Render CORS_ALLOWED_ORIGINS=https://prepflow-vercel-static.vercel.app,https://thaijoint-prepflow.vercel.app,https://localhost,http://10.0.2.2
Render MAIL_MAILER=smtp, MAIL_HOST=smtp-relay.brevo.com, MAIL_PORT=2525, MAIL_ENCRYPTION=tls

After first successful migration, set RUN_MIGRATIONS=false unless a new migration is intentionally being deployed.

Verification Gates

Run these before marking a change complete:

cd api
$env:PATH = 'C:\xampp\php;' + $env:PATH
php artisan test
vendor/bin/pint --test

cd ..\apps\web
bun run build

cd ..\mobile
bun run sync

Latest verified gate after the Android notification, admin prep, and README rubric-packaging fixes:

bun run build: passed
bun run build:mobile: passed
Android assembleDebug: passed
PHP tests: 122 passed (429 assertions)
Pint: passed
Debug APK SHA-256: 13B8A6D256766CFC39BF363C49BEECAC6DEF41B3D4FE5290F339CB5891545EED

Useful deployed smoke checks:

Invoke-WebRequest -Uri https://prepflow-api.onrender.com/api/menu -UseBasicParsing
Invoke-WebRequest -Uri https://prepflow-api.onrender.com/api/payment-methods -UseBasicParsing
Invoke-WebRequest -Uri https://prepflow-vercel-static.vercel.app/api/menu -UseBasicParsing

OCR diagnostic:

cd api
$env:PATH='C:\xampp\php;' + $env:PATH
$env:OCR_TECHNIQUE='tesseract'
$env:TESSERACT_BIN='C:\Program Files\Tesseract-OCR\tesseract.exe'
php artisan ocr:receipt-check --image-file='D:\Users\Carl\Downloads\724483969_1335935291314941_416704984620132909_n.jpg'

Engineering Constraints

  • Bun only. Do not use npm/yarn/pnpm for repo tasks.
  • Do not commit .env, Cloudinary keys, TiDB passwords, Render secrets, vendor/, node_modules/, dist/, or generated android/.
  • Keep graded primitives visible: explicit json_encode responses, session regeneration on auth changes, PDO/prepared statements/transactions for critical writes.
  • Any schema/enum change must update all mirrors: db/schema.sql, Laravel migration, packages/shared/src/index.ts, and apps/web/src/types.ts.
  • No payment processor APIs, card processing, courier dispatch APIs, multi-tenant support, or PayMongo.
  • Every async UI path should have loading state and user-visible error feedback.

Read DECISIONS.md before changing product scope or architecture.

Documentation Index

Document Purpose
DECISIONS.md Locked product scope, architecture, and tradeoffs
docs/planning/submission-readiness-2026-06-29.md Current rubric readiness audit and latest verification evidence
docs/planning/defense-cheat-sheet.md Short panel-question answers with source files to show
LICENSE MIT terms and brand/media notice
docs/SYSTEM-DIAGRAMS.md Rubric diagram index: Structurizr C4 model plus DFD, flowchart, sequence, and ERD
docs/architecture/workspace.dsl Structurizr DSL source of truth for the C4 architecture model
docs/screenshots/ Curated README and presentation screenshots
docs/ARCHITECTURE.md System design and rubric traceability
docs/ERD.md Entity relationship model
docs/DFD.md Data flow diagrams
docs/deployment/free-tier.md Render + TiDB + Vercel deployment guide
docs/planning/session-final-report.md Historical implementation and verification report
docs/planning/deployment-hardening-session-2026-06-28.md Historical deployment/auth/email/OCR/APK hardening session log
docs/planning/completion-audit.md Historical audit baseline
apps/mobile/README.md Capacitor/Android build notes

Team

Member Role and contribution
Ortiz, Carl Kristian R. Sole full-stack implementer: architecture, frontend, backend, database, deployment, Android packaging, documentation, and integration
Alferez, Rey Lawrence P. UI/UX and Figma direction, screen references, user-flow review
Patanao, Xian Zheniel Asha R. Customer-flow QA, responsive checks, presentation readiness
Paulo, Alfonso Leon A. Admin/mobile QA, demo testing

License

MIT. See LICENSE.

Thai Joint PH names, logos, product photos, and related brand assets remain the property of their respective owners. MIT covers PrepFlow source code and project docs; brand media is not free for unrelated commercial reuse.

Course Note

Built for CMPE 364 (Web and Mobile Systems), Polytechnic University of the Philippines, under Engr. Arlene B. Canlas. Final group project; defended and graded. Published here as a standalone portfolio product.

About

Thai Joint PH ordering, payment verification, and kitchen prep automation. Laravel API, React SPA, Capacitor Android.

Topics

Resources

License

Stars

1 star

Watchers

0 watching

Forks

Packages

 
 
 

Contributors