forked from jamesp/sasa-membership
main #5
+3
-1
@@ -6,7 +6,7 @@ This project aims to develop a comprehensive membership management system for th
|
|||||||
|
|
||||||
## Current Implementation Status
|
## Current Implementation Status
|
||||||
|
|
||||||
The app now includes a FastAPI backend, React/Vite frontend, Docker Compose development gateway, Alembic migrations, Square payment integration, SMTP2GO email integration, event/RSVP endpoints, configurable profile questions, privacy/terms pages, feature flags, and a fast test gate in `restart.sh`.
|
The app now includes a FastAPI backend, React/Vite frontend, Docker Compose development gateway, Alembic migrations, Square payment integration, SMTP2GO email integration, ESP RFID provisioning/time-sync/tap tracking, event/RSVP endpoints, configurable profile questions, privacy/terms pages, feature flags, UTC backend timestamps with London-facing frontend formatting, and a fast test gate in `restart.sh`.
|
||||||
|
|
||||||
## Core Features
|
## Core Features
|
||||||
|
|
||||||
@@ -26,6 +26,8 @@ The app now includes a FastAPI backend, React/Vite frontend, Docker Compose deve
|
|||||||
- **Membership Tier Management**: Configure different membership levels and associated fees
|
- **Membership Tier Management**: Configure different membership levels and associated fees
|
||||||
- **Profile Question Management**: Create, edit, deactivate, order, and configure dependencies for member profile questions
|
- **Profile Question Management**: Create, edit, deactivate, order, and configure dependencies for member profile questions
|
||||||
- **Meeting/Event Management**: Create, edit, and manage events, track RSVPs and attendance
|
- **Meeting/Event Management**: Create, edit, and manage events, track RSVPs and attendance
|
||||||
|
- **Timezone Handling**: Persist timestamps in UTC, display member-facing times in Europe/London, and convert event input back to UTC before saving
|
||||||
|
- **ESP RFID Readers**: Reader registration, time sync, taps, attendance sessions, and queued card-writing jobs are implemented end to end
|
||||||
- **Email Management**: Edit database-backed email templates with escaped previews, send test emails, and monitor SMTP2GO bounces
|
- **Email Management**: Edit database-backed email templates with escaped previews, send test emails, and monitor SMTP2GO bounces
|
||||||
- **Feature Flags**: View backend feature flags and reload them from the super-admin interface
|
- **Feature Flags**: View backend feature flags and reload them from the super-admin interface
|
||||||
- **Reporting**: Planned reports on membership statistics and payment status
|
- **Reporting**: Planned reports on membership statistics and payment status
|
||||||
|
|||||||
+11
-2
@@ -30,10 +30,10 @@ membership/
|
|||||||
│ │ ├── email_templates.py
|
│ │ ├── email_templates.py
|
||||||
│ │ ├── events.py # Events and RSVPs
|
│ │ ├── events.py # Events and RSVPs
|
||||||
│ │ └── feature_flags.py
|
│ │ └── feature_flags.py
|
||||||
│ ├── core/ # Config, database, security, default data
|
│ ├── core/ # Config, database, security, datetime helpers, default data
|
||||||
│ ├── models/ # SQLAlchemy models
|
│ ├── models/ # SQLAlchemy models
|
||||||
│ ├── schemas/ # Pydantic schemas
|
│ ├── schemas/ # Pydantic schemas
|
||||||
│ ├── services/ # Email, bounce, Square, feature flags
|
│ ├── services/ # Email, bounce, Square, attendance, feature flags
|
||||||
│ └── tests/ # Fast backend pytest unit tests
|
│ └── tests/ # Fast backend pytest unit tests
|
||||||
│
|
│
|
||||||
├── docker/
|
├── docker/
|
||||||
@@ -64,9 +64,11 @@ membership/
|
|||||||
- **`backend/app/core/config.py`** - Settings management.
|
- **`backend/app/core/config.py`** - Settings management.
|
||||||
- **`backend/app/core/init_db.py`** - Default membership tiers, super admin, email templates, and profile questions.
|
- **`backend/app/core/init_db.py`** - Default membership tiers, super admin, email templates, and profile questions.
|
||||||
- **`backend/app/core/security.py`** - JWT tokens and password hashing.
|
- **`backend/app/core/security.py`** - JWT tokens and password hashing.
|
||||||
|
- **`backend/app/core/datetime.py`** - UTC helpers and Zulu serialization helpers.
|
||||||
- **`backend/app/models/models.py`** - Database tables.
|
- **`backend/app/models/models.py`** - Database tables.
|
||||||
- **`backend/app/schemas/schemas.py`** - API request/response models.
|
- **`backend/app/schemas/schemas.py`** - API request/response models.
|
||||||
- **`backend/app/tests/test_profile_question_logic.py`** - Fast backend unit tests for profile answer validation.
|
- **`backend/app/tests/test_profile_question_logic.py`** - Fast backend unit tests for profile answer validation.
|
||||||
|
- **`backend/app/tests/test_datetime_utc.py`** - UTC normalization and serialization tests.
|
||||||
|
|
||||||
### Frontend Application
|
### Frontend Application
|
||||||
- **`frontend/src/pages/Dashboard.tsx`** - Main member/admin dashboard.
|
- **`frontend/src/pages/Dashboard.tsx`** - Main member/admin dashboard.
|
||||||
@@ -76,7 +78,9 @@ membership/
|
|||||||
- **`frontend/src/components/ProfileQuestionsForm.tsx`** - Member/admin answer form with dependency handling.
|
- **`frontend/src/components/ProfileQuestionsForm.tsx`** - Member/admin answer form with dependency handling.
|
||||||
- **`frontend/src/components/EmailTemplateManagement.tsx`** - Email template editing.
|
- **`frontend/src/components/EmailTemplateManagement.tsx`** - Email template editing.
|
||||||
- **`frontend/src/components/BounceManagement.tsx`** - SMTP2GO bounce management.
|
- **`frontend/src/components/BounceManagement.tsx`** - SMTP2GO bounce management.
|
||||||
|
- **`frontend/src/components/EspReaderManagement.tsx`** - ESP reader, card, tap, and attendance admin UI.
|
||||||
- **`frontend/src/utils/profileQuestionLogic.test.ts`** - Fast frontend unit tests for profile-question visibility/editability.
|
- **`frontend/src/utils/profileQuestionLogic.test.ts`** - Fast frontend unit tests for profile-question visibility/editability.
|
||||||
|
- **`frontend/src/utils/timezone.ts`** - Europe/London display helpers and UTC conversion utilities.
|
||||||
|
|
||||||
## API Endpoints
|
## API Endpoints
|
||||||
|
|
||||||
@@ -87,6 +91,7 @@ membership/
|
|||||||
- **`payments.py`** - Payment history, manual payments, Square config/process/refund.
|
- **`payments.py`** - Payment history, manual payments, Square config/process/refund.
|
||||||
- **`events.py`** - Event CRUD, upcoming events, RSVP create/update, RSVP listing.
|
- **`events.py`** - Event CRUD, upcoming events, RSVP create/update, RSVP listing.
|
||||||
- **`email.py`** - SMTP2GO test emails, welcome email tests, bounce webhook, bounce stats, cleanup, deactivation.
|
- **`email.py`** - SMTP2GO test emails, welcome email tests, bounce webhook, bounce stats, cleanup, deactivation.
|
||||||
|
- **`esp.py`** - ESP reader provisioning, time sync, tap capture, dashboard login, attendance, and queued write jobs.
|
||||||
- **`email_templates.py`** - Database-backed template listing, lookup, update, and default seeding.
|
- **`email_templates.py`** - Database-backed template listing, lookup, update, and default seeding.
|
||||||
- **`feature_flags.py`** - Public feature flag listing/lookup and super-admin-only reload.
|
- **`feature_flags.py`** - Public feature flag listing/lookup and super-admin-only reload.
|
||||||
|
|
||||||
@@ -104,6 +109,10 @@ Fully implemented:
|
|||||||
- **EmailTemplate** - Editable database-backed email templates.
|
- **EmailTemplate** - Editable database-backed email templates.
|
||||||
- **EmailBounce** - SMTP2GO bounce, complaint, and unsubscribe tracking.
|
- **EmailBounce** - SMTP2GO bounce, complaint, and unsubscribe tracking.
|
||||||
- **PasswordResetToken** - One-time password reset support.
|
- **PasswordResetToken** - One-time password reset support.
|
||||||
|
- **EspReader** - Provisioned RFID readers with UTC heartbeat and time-sync data.
|
||||||
|
- **RfidTap** - UTC-normalized RFID tap records.
|
||||||
|
- **AttendanceSession** - Attendance sessions driven by RFID taps.
|
||||||
|
- **RfidCardWriteJob** - Queued RFID card write jobs.
|
||||||
- **VolunteerRole** - Volunteer role definitions.
|
- **VolunteerRole** - Volunteer role definitions.
|
||||||
- **VolunteerAssignment** - Member-to-role assignments.
|
- **VolunteerAssignment** - Member-to-role assignments.
|
||||||
- **VolunteerSchedule** - Volunteer shift schedules.
|
- **VolunteerSchedule** - Volunteer shift schedules.
|
||||||
|
|||||||
@@ -16,6 +16,8 @@ Wait until you see "Application startup complete", then press Ctrl+C.
|
|||||||
- API: http://localhost:8050/api/v1
|
- API: http://localhost:8050/api/v1
|
||||||
- Docs: http://localhost:8050/docs
|
- Docs: http://localhost:8050/docs
|
||||||
|
|
||||||
|
API datetimes are stored and returned in UTC/Zulu. The frontend shows member-facing times in Europe/London and converts event input back to UTC before saving.
|
||||||
|
|
||||||
Set `APP_PORT` in `.env` / `.env.example` to change `8050`.
|
Set `APP_PORT` in `.env` / `.env.example` to change `8050`.
|
||||||
For Square payment form testing, use HTTPS at `https://localhost:8443`.
|
For Square payment form testing, use HTTPS at `https://localhost:8443`.
|
||||||
Set `APP_TLS_PORT` in `.env` / `.env.example` to change `8443`.
|
Set `APP_TLS_PORT` in `.env` / `.env.example` to change `8443`.
|
||||||
@@ -137,6 +139,12 @@ docker compose logs -f gateway
|
|||||||
2. Members can view upcoming events and submit RSVP status
|
2. Members can view upcoming events and submit RSVP status
|
||||||
3. Admins can view RSVP lists and attendance data
|
3. Admins can view RSVP lists and attendance data
|
||||||
|
|
||||||
|
### ESP RFID readers
|
||||||
|
1. Readers register with `/api/v1/esp/device/register`
|
||||||
|
2. Readers sync clocks from `/api/v1/esp/device/time`
|
||||||
|
3. Tap, heartbeat, and write-job timestamps are UTC-normalized in the backend
|
||||||
|
4. Admins can review readers, taps, attendance, and card-write jobs from the ESP screens
|
||||||
|
|
||||||
### Manage email templates and bounces
|
### Manage email templates and bounces
|
||||||
1. Super admins can edit database-backed email templates; previews are shown as escaped HTML text
|
1. Super admins can edit database-backed email templates; previews are shown as escaped HTML text
|
||||||
2. SMTP2GO bounce webhooks are stored and visible in bounce management
|
2. SMTP2GO bounce webhooks are stored and visible in bounce management
|
||||||
|
|||||||
@@ -10,6 +10,8 @@ A membership management system for Swansea Airport Stakeholders' Alliance, built
|
|||||||
- **Membership tiers**: Configurable Personal, Aircraft Owners, Corporate, and custom tiers with annual fees, descriptions, active/inactive state, and benefits.
|
- **Membership tiers**: Configurable Personal, Aircraft Owners, Corporate, and custom tiers with annual fees, descriptions, active/inactive state, and benefits.
|
||||||
- **Memberships and payments**: Membership lifecycle tracking, Square card payments, cash/check/manual payments, dummy test payments, payment history, transaction IDs, refund state, and payment-to-membership linking.
|
- **Memberships and payments**: Membership lifecycle tracking, Square card payments, cash/check/manual payments, dummy test payments, payment history, transaction IDs, refund state, and payment-to-membership linking.
|
||||||
- **Events and RSVPs**: Event CRUD, upcoming event listing, member RSVP updates, RSVP status tracking, attendance fields, and admin RSVP visibility.
|
- **Events and RSVPs**: Event CRUD, upcoming event listing, member RSVP updates, RSVP status tracking, attendance fields, and admin RSVP visibility.
|
||||||
|
- **Time handling**: Backend timestamps are stored and returned as UTC/Zulu, the frontend renders member-facing dates and times in Europe/London, and event entry is converted back to UTC before save.
|
||||||
|
- **ESP RFID**: Reader provisioning, heartbeat, time sync, tap capture, queued card writes, and admin review of readers/cards/attendance.
|
||||||
- **Volunteer and profile data**: Volunteer flag/level support, configurable member profile questions, conditional questions, admin-only answers, seeded aviation/volunteering questions, and data models for volunteer roles, assignments, schedules, and certificates.
|
- **Volunteer and profile data**: Volunteer flag/level support, configurable member profile questions, conditional questions, admin-only answers, seeded aviation/volunteering questions, and data models for volunteer roles, assignments, schedules, and certificates.
|
||||||
- **Email system**: SMTP2GO-backed email sending, default database templates, editable templates, welcome/password-reset/test emails, bounce webhooks, bounce stats, cleanup, and manual deactivation.
|
- **Email system**: SMTP2GO-backed email sending, default database templates, editable templates, welcome/password-reset/test emails, bounce webhooks, bounce stats, cleanup, and manual deactivation.
|
||||||
- **Feature flags**: Backend feature-flag service with frontend context and admin status/reload controls.
|
- **Feature flags**: Backend feature-flag service with frontend context and admin status/reload controls.
|
||||||
@@ -49,11 +51,13 @@ membership/
|
|||||||
│ │ │ │ ├── email.py # SMTP2GO email and bounces
|
│ │ │ │ ├── email.py # SMTP2GO email and bounces
|
||||||
│ │ │ │ ├── email_templates.py
|
│ │ │ │ ├── email_templates.py
|
||||||
│ │ │ │ ├── events.py # Events and RSVPs
|
│ │ │ │ ├── events.py # Events and RSVPs
|
||||||
|
│ │ │ │ ├── esp.py # ESP RFID provisioning, taps, attendance, write jobs
|
||||||
│ │ │ │ └── feature_flags.py
|
│ │ │ │ └── feature_flags.py
|
||||||
│ │ │ └── dependencies.py # Auth dependencies
|
│ │ │ └── dependencies.py # Auth dependencies
|
||||||
│ │ ├── core/
|
│ │ ├── core/
|
||||||
│ │ │ ├── config.py # Configuration
|
│ │ │ ├── config.py # Configuration
|
||||||
│ │ │ ├── database.py # Database setup
|
│ │ │ ├── database.py # Database setup
|
||||||
|
│ │ │ ├── datetime.py # UTC helpers and Zulu serialization helpers
|
||||||
│ │ │ └── security.py # Security utilities
|
│ │ │ └── security.py # Security utilities
|
||||||
│ │ ├── models/
|
│ │ ├── models/
|
||||||
│ │ │ └── models.py # Database models
|
│ │ │ └── models.py # Database models
|
||||||
@@ -64,11 +68,11 @@ membership/
|
|||||||
│ └── requirements.txt
|
│ └── requirements.txt
|
||||||
├── frontend/
|
├── frontend/
|
||||||
│ ├── src/
|
│ ├── src/
|
||||||
│ │ ├── components/ # Dashboard, payment, admin, profile components
|
│ │ ├── components/ # Dashboard, payment, admin, profile, ESP components
|
||||||
│ │ ├── contexts/ # Feature flag context
|
│ │ ├── contexts/ # Feature flag, toast, and confirm contexts
|
||||||
│ │ ├── pages/ # Login, register, dashboard, policy pages
|
│ │ ├── pages/ # Login, register, dashboard, policy pages
|
||||||
│ │ ├── services/ # API clients
|
│ │ ├── services/ # API clients
|
||||||
│ │ └── utils/ # Tested frontend logic
|
│ │ └── utils/ # Tested frontend logic and timezone helpers
|
||||||
├── docker-compose.yml
|
├── docker-compose.yml
|
||||||
├── .env.example
|
├── .env.example
|
||||||
└── README.md
|
└── README.md
|
||||||
@@ -261,6 +265,38 @@ docker compose --profile prod down
|
|||||||
- `GET /api/v1/feature-flags/flags` - List flags
|
- `GET /api/v1/feature-flags/flags` - List flags
|
||||||
- `POST /api/v1/feature-flags/flags/reload` - Reload flags (super admin)
|
- `POST /api/v1/feature-flags/flags/reload` - Reload flags (super admin)
|
||||||
|
|
||||||
|
### ESP RFID
|
||||||
|
- `POST /api/v1/esp/device/register` - Reader registration and one-time token issuance
|
||||||
|
- `GET /api/v1/esp/device/provisioning-status` - Poll reader provisioning
|
||||||
|
- `GET /api/v1/esp/device/time` - UTC clock sync for ESP firmware
|
||||||
|
- `POST /api/v1/esp/device/heartbeat` - Reader heartbeat with UTC server time
|
||||||
|
- `POST /api/v1/esp/device/taps` - RFID tap capture with UTC-normalized timestamps
|
||||||
|
- `GET /api/v1/esp/device/write-jobs/next` - Poll queued card write job
|
||||||
|
- `POST /api/v1/esp/device/write-jobs/{job_id}/complete` - Complete a queued write job
|
||||||
|
- `POST /api/v1/esp/device/dashboard-login` - Validate ESP-hosted dashboard login
|
||||||
|
- `GET /api/v1/esp/admin/readers` - Admin reader list
|
||||||
|
- `POST /api/v1/esp/admin/readers` - Admin reader create/provision fallback
|
||||||
|
- `PUT /api/v1/esp/admin/readers/{reader_id}` - Admin reader update / key rotation
|
||||||
|
- `POST /api/v1/esp/admin/readers/{reader_id}/approve` - Approve a reader
|
||||||
|
- `POST /api/v1/esp/admin/readers/{reader_id}/reject` - Reject a reader
|
||||||
|
- `DELETE /api/v1/esp/admin/readers/{reader_id}` - Delete a reader
|
||||||
|
- `GET /api/v1/esp/admin/cards` - Admin RFID card list
|
||||||
|
- `POST /api/v1/esp/admin/cards` - Create RFID card
|
||||||
|
- `PUT /api/v1/esp/admin/cards/{card_id}` - Update RFID card
|
||||||
|
- `GET /api/v1/esp/admin/write-jobs` - Admin queued write jobs
|
||||||
|
- `POST /api/v1/esp/admin/write-jobs` - Queue a write job
|
||||||
|
- `POST /api/v1/esp/admin/write-jobs/{job_id}/cancel` - Cancel a queued write job
|
||||||
|
- `GET /api/v1/esp/admin/taps` - Admin tap history
|
||||||
|
- `GET /api/v1/esp/admin/attendance` - Admin attendance sessions
|
||||||
|
- `POST /api/v1/esp/admin/attendance/close-stale` - Close stale attendance sessions
|
||||||
|
|
||||||
|
## Time Handling
|
||||||
|
|
||||||
|
- Database timestamps are stored as UTC and serialized as Zulu (`...Z`) in API responses.
|
||||||
|
- Frontend display uses Europe/London for member-facing dates and times.
|
||||||
|
- Event creation/editing converts London-local input back to UTC before sending it to the backend.
|
||||||
|
- ESP devices sync their clocks from `/api/v1/esp/device/time` and persist tap times as UTC.
|
||||||
|
|
||||||
## Docker Compose Commands
|
## Docker Compose Commands
|
||||||
|
|
||||||
### Basic Operations
|
### Basic Operations
|
||||||
|
|||||||
Reference in New Issue
Block a user