← eventa overview

codex round 3 — raw transcript

The unedited stdout from the codex CLI. Kept here for traceability.

Reading additional input from stdin...
OpenAI Codex v0.125.0 (research preview)
--------
workdir: /home/teodor/little-projects/heapzilla-ai/android/counter-app
model: gpt-5.5
provider: openai
approval: never
sandbox: read-only
reasoning effort: medium
reasoning summaries: none
session id: 019dcea0-0693-7300-9fd1-2059dea7f4e4
--------
user
Now architect the technical side of "eventa", a personal event-planning app. Final MVP feature set is:

1. Event Brief — title, dates, location, type, est. guests, rough budget
2. Guest List with RSVP — guests, households, RSVP, dietary, lodging
3. Private Planning Checklist (incorporating supply/packing) — tasks with category, owner, due date
4. Deadline Timeline — chronological view of incomplete tasks (overdue / this week / this month / later)
5. Budget Buckets — estimated vs actual, by category, paid-by

Constraints (this is the user environment):
- Self-hosted on a small home server (4 cores, 16 GB RAM)
- Python preferred (Flask is already used in similar apps in this stack)
- Should live behind nginx with TLS (already wired)
- Single-user (or family) — no multi-tenant complexity needed
- SQLite is fine; PostgreSQL is overkill but acceptable
- Mobile-first UI (used a lot from phone)
- Must work offline-tolerant for the event day (PWA-style cache is bonus)

Produce:

A. **Stack**: language, framework, persistence, frontend approach (rendered HTML vs SPA), styling. One paragraph each, decisive choices, no "could also use".

B. **Data Model**: list the tables/entities needed for the MVP. For each: name, key fields, relationships. SQL-ish but informal.

C. **Routing / Endpoints**: the 8-12 HTTP routes that cover the MVP UI. Method + path + brief description.

D. **Risks & Cuts for V1**: what specific simplifications must we accept to ship a small, robust V1 instead of a sprawling project?

Be concrete. Aim for a doc a junior engineer could implement directly.
codex
**A. Stack**

**Language**  
Use Python 3.12. It fits the existing home-server stack, is easy to deploy, and is more than sufficient for a small single-user event-planning app.

**Framework**  
Use Flask with the application factory pattern, Blueprints for feature areas, and Flask-WTF for forms. Keep the app server-rendered and boring: request, validate form, write SQLite, redirect. Run it behind nginx via Gunicorn using a systemd service.

**Persistence**  
Use SQLite with SQLAlchemy ORM and Alembic migrations. Store the database as a single file under the app data directory, for example `/var/lib/eventa/eventa.sqlite3`, and enable WAL mode. PostgreSQL is unnecessary for this MVP.

**Frontend Approach**  
Use rendered HTML with Jinja templates, not a SPA. Add small amounts of JavaScript only where it improves mobile workflows, such as inline RSVP updates, collapsible timeline sections, and “mark task done” buttons. The app should remain useful without JavaScript for robustness.

**Styling**  
Use Tailwind CSS compiled at build time, plus a small local CSS file for app-specific layout. Design mobile-first: bottom navigation, large tap targets, compact cards, sticky action buttons, and forms split into short sections. Avoid a component framework for V1.

**Offline / PWA**  
Add a minimal service worker that caches the app shell, CSS, JS, icons, and selected read-only pages for the active event: overview, guest list, checklist, timeline, and budget. Treat offline mode as read-mostly in V1. Do not attempt full offline writes or conflict resolution yet.

---

**B. Data Model**

```sql
events
- id
- title
- start_date
- end_date
- location_name
- location_address
- event_type
- estimated_guest_count
- rough_budget_cents
- notes
- created_at
- updated_at
```

Central record for an event. V1 can support multiple events in the database, but the UI should focus on one active event at a time.

```sql
households
- id
- event_id -> events.id
- name
- primary_contact_name
- email
- phone
- address
- notes
- created_at
- updated_at
```

Groups guests together for invitations, lodging, and RSVP tracking.

```sql
guests
- id
- event_id -> events.id
- household_id -> households.id nullable
- first_name
- last_name
- display_name
- email
- phone
- rsvp_status enum: unknown, invited, yes, no, maybe
- dietary_notes
- lodging_needed boolean
- lodging_notes
- notes
- created_at
- updated_at
```

Individual invitees. Belongs to one event and optionally one household.

```sql
task_categories
- id
- event_id -> events.id
- name
- sort_order
```

Checklist categories such as Food, Venue, Travel, Supplies, Packing, Decor, Admin.

```sql
tasks
- id
- event_id -> events.id
- category_id -> task_categories.id nullable
- title
- description
- owner_name
- due_date
- completed_at nullable
- priority enum: low, normal, high
- sort_order
- created_at
- updated_at
```

Private planning checklist. Supply and packing items are just tasks with categories like `Supplies` or `Packing`.

```sql
budget_categories
- id
- event_id -> events.id
- name
- sort_order
```

Budget buckets such as Food, Drinks, Venue, Lodging, Transport, Supplies, Gifts, Misc.

```sql
budget_items
- id
- event_id -> events.id
- category_id -> budget_categories.id
- name
- estimated_cents
- actual_cents nullable
- paid_by
- paid_at nullable
- vendor
- notes
- created_at
- updated_at
```

Line items grouped into budget buckets. Estimated and actual totals can be calculated from this table.

Optional but useful:

```sql
app_settings
- id
- active_event_id -> events.id nullable
- currency_code
- created_at
- updated_at
```

Keeps the app focused on one event by default.

---

**C. Routing / Endpoints**

```http
GET /
```

Redirect to the active event dashboard, or to event creation if no event exists.

```http
GET /events/new
POST /events
```

Create the event brief: title, dates, location, type, estimated guests, rough budget.

```http
GET /events/<event_id>
POST /events/<event_id>
```

View and edit the event dashboard/brief. Shows summary counts: RSVP totals, open tasks, overdue tasks, estimated vs actual budget.

```http
GET /events/<event_id>/guests
POST /events/<event_id>/guests
```

Guest list view and create guest form. Include filters for RSVP status, lodging needed, and household.

```http
GET /events/<event_id>/guests/<guest_id>
POST /events/<event_id>/guests/<guest_id>
```

Edit one guest: RSVP, dietary notes, lodging, contact info, household assignment.

```http
GET /events/<event_id>/households
POST /events/<event_id>/households
```

Manage households. Keep this simple: create household, assign guests, edit household notes.

```http
GET /events/<event_id>/checklist
POST /events/<event_id>/tasks
```

Checklist view grouped by category. Create a task with category, owner, due date, priority.

```http
POST /events/<event_id>/tasks/<task_id>
POST /events/<event_id>/tasks/<task_id>/complete
```

Edit a task or mark it complete/incomplete. Use redirect responses; JavaScript can progressively enhance this.

```http
GET /events/<event_id>/timeline
```

Deadline timeline of incomplete tasks grouped into Overdue, This Week, This Month, Later.

```http
GET /events/<event_id>/budget
POST /events/<event_id>/budget-items
```

Budget bucket view. Shows estimated, actual, and delta by category. Create budget items.

```http
POST /events/<event_id>/budget-items/<item_id>
```

Edit or delete a budget item.

```http
GET /offline
GET /service-worker.js
GET /manifest.webmanifest
```

PWA support: offline fallback page, service worker, and manifest.

---

**D. Risks & Cuts For V1**

Use a single shared login or reverse-proxy auth. Do not build users, roles, permissions, invitations, password resets, or family accounts in V1.

Do not build public RSVP links. RSVP is managed privately inside the app. Public guest self-service sounds small, but it introduces authentication, spam protection, link expiry, validation, and privacy issues.

Do not build complex recurring tasks, dependencies, templates, or automation. A task has title, category, owner, due date, and completed state. That is enough.

Do not build full offline editing. Cache read-only event-day pages so the plan is visible when the phone has bad signal. Writes require network in V1.

Do not build payment settlement. `paid_by`, `actual_cents`, and `paid_at` are enough. No reimbursements, balances, receipt uploads, or accounting exports.

Do not over-model guests. Keep RSVP as one status per guest. Avoid per-meal RSVP, plus-ones, invitation batches, seating charts, and email sending.

Do not build a generalized project-management app. Categories are simple labels scoped to an event. Owners are plain text names, not user accounts.

Do not add PostgreSQL, Redis, Celery, background jobs, or API-first architecture. Flask plus SQLite is the right size for this environment.

Do not make the UI desktop-first. Every page should work well on a phone: fast add buttons, short forms, large controls, and readable grouped lists.

Do not optimize for many simultaneous events. The database may support multiple events, but the product should behave like “my current event planner” until there is a real need for archives and switching.
2026-04-27T11:08:46.095666Z ERROR codex_core::session: failed to record rollout items: thread 019dcea0-0693-7300-9fd1-2059dea7f4e4 not found
tokens used
4,115
**A. Stack**

**Language**  
Use Python 3.12. It fits the existing home-server stack, is easy to deploy, and is more than sufficient for a small single-user event-planning app.

**Framework**  
Use Flask with the application factory pattern, Blueprints for feature areas, and Flask-WTF for forms. Keep the app server-rendered and boring: request, validate form, write SQLite, redirect. Run it behind nginx via Gunicorn using a systemd service.

**Persistence**  
Use SQLite with SQLAlchemy ORM and Alembic migrations. Store the database as a single file under the app data directory, for example `/var/lib/eventa/eventa.sqlite3`, and enable WAL mode. PostgreSQL is unnecessary for this MVP.

**Frontend Approach**  
Use rendered HTML with Jinja templates, not a SPA. Add small amounts of JavaScript only where it improves mobile workflows, such as inline RSVP updates, collapsible timeline sections, and “mark task done” buttons. The app should remain useful without JavaScript for robustness.

**Styling**  
Use Tailwind CSS compiled at build time, plus a small local CSS file for app-specific layout. Design mobile-first: bottom navigation, large tap targets, compact cards, sticky action buttons, and forms split into short sections. Avoid a component framework for V1.

**Offline / PWA**  
Add a minimal service worker that caches the app shell, CSS, JS, icons, and selected read-only pages for the active event: overview, guest list, checklist, timeline, and budget. Treat offline mode as read-mostly in V1. Do not attempt full offline writes or conflict resolution yet.

---

**B. Data Model**

```sql
events
- id
- title
- start_date
- end_date
- location_name
- location_address
- event_type
- estimated_guest_count
- rough_budget_cents
- notes
- created_at
- updated_at
```

Central record for an event. V1 can support multiple events in the database, but the UI should focus on one active event at a time.

```sql
households
- id
- event_id -> events.id
- name
- primary_contact_name
- email
- phone
- address
- notes
- created_at
- updated_at
```

Groups guests together for invitations, lodging, and RSVP tracking.

```sql
guests
- id
- event_id -> events.id
- household_id -> households.id nullable
- first_name
- last_name
- display_name
- email
- phone
- rsvp_status enum: unknown, invited, yes, no, maybe
- dietary_notes
- lodging_needed boolean
- lodging_notes
- notes
- created_at
- updated_at
```

Individual invitees. Belongs to one event and optionally one household.

```sql
task_categories
- id
- event_id -> events.id
- name
- sort_order
```

Checklist categories such as Food, Venue, Travel, Supplies, Packing, Decor, Admin.

```sql
tasks
- id
- event_id -> events.id
- category_id -> task_categories.id nullable
- title
- description
- owner_name
- due_date
- completed_at nullable
- priority enum: low, normal, high
- sort_order
- created_at
- updated_at
```

Private planning checklist. Supply and packing items are just tasks with categories like `Supplies` or `Packing`.

```sql
budget_categories
- id
- event_id -> events.id
- name
- sort_order
```

Budget buckets such as Food, Drinks, Venue, Lodging, Transport, Supplies, Gifts, Misc.

```sql
budget_items
- id
- event_id -> events.id
- category_id -> budget_categories.id
- name
- estimated_cents
- actual_cents nullable
- paid_by
- paid_at nullable
- vendor
- notes
- created_at
- updated_at
```

Line items grouped into budget buckets. Estimated and actual totals can be calculated from this table.

Optional but useful:

```sql
app_settings
- id
- active_event_id -> events.id nullable
- currency_code
- created_at
- updated_at
```

Keeps the app focused on one event by default.

---

**C. Routing / Endpoints**

```http
GET /
```

Redirect to the active event dashboard, or to event creation if no event exists.

```http
GET /events/new
POST /events
```

Create the event brief: title, dates, location, type, estimated guests, rough budget.

```http
GET /events/<event_id>
POST /events/<event_id>
```

View and edit the event dashboard/brief. Shows summary counts: RSVP totals, open tasks, overdue tasks, estimated vs actual budget.

```http
GET /events/<event_id>/guests
POST /events/<event_id>/guests
```

Guest list view and create guest form. Include filters for RSVP status, lodging needed, and household.

```http
GET /events/<event_id>/guests/<guest_id>
POST /events/<event_id>/guests/<guest_id>
```

Edit one guest: RSVP, dietary notes, lodging, contact info, household assignment.

```http
GET /events/<event_id>/households
POST /events/<event_id>/households
```

Manage households. Keep this simple: create household, assign guests, edit household notes.

```http
GET /events/<event_id>/checklist
POST /events/<event_id>/tasks
```

Checklist view grouped by category. Create a task with category, owner, due date, priority.

```http
POST /events/<event_id>/tasks/<task_id>
POST /events/<event_id>/tasks/<task_id>/complete
```

Edit a task or mark it complete/incomplete. Use redirect responses; JavaScript can progressively enhance this.

```http
GET /events/<event_id>/timeline
```

Deadline timeline of incomplete tasks grouped into Overdue, This Week, This Month, Later.

```http
GET /events/<event_id>/budget
POST /events/<event_id>/budget-items
```

Budget bucket view. Shows estimated, actual, and delta by category. Create budget items.

```http
POST /events/<event_id>/budget-items/<item_id>
```

Edit or delete a budget item.

```http
GET /offline
GET /service-worker.js
GET /manifest.webmanifest
```

PWA support: offline fallback page, service worker, and manifest.

---

**D. Risks & Cuts For V1**

Use a single shared login or reverse-proxy auth. Do not build users, roles, permissions, invitations, password resets, or family accounts in V1.

Do not build public RSVP links. RSVP is managed privately inside the app. Public guest self-service sounds small, but it introduces authentication, spam protection, link expiry, validation, and privacy issues.

Do not build complex recurring tasks, dependencies, templates, or automation. A task has title, category, owner, due date, and completed state. That is enough.

Do not build full offline editing. Cache read-only event-day pages so the plan is visible when the phone has bad signal. Writes require network in V1.

Do not build payment settlement. `paid_by`, `actual_cents`, and `paid_at` are enough. No reimbursements, balances, receipt uploads, or accounting exports.

Do not over-model guests. Keep RSVP as one status per guest. Avoid per-meal RSVP, plus-ones, invitation batches, seating charts, and email sending.

Do not build a generalized project-management app. Categories are simple labels scoped to an event. Owners are plain text names, not user accounts.

Do not add PostgreSQL, Redis, Celery, background jobs, or API-first architecture. Flask plus SQLite is the right size for this environment.

Do not make the UI desktop-first. Every page should work well on a phone: fast add buttons, short forms, large controls, and readable grouped lists.

Do not optimize for many simultaneous events. The database may support multiple events, but the product should behave like “my current event planner” until there is a real need for archives and switching.