chore: remove Trello integration — MCP, task tracking, csv, env vars

This commit is contained in:
Joakim Mörling 2026-04-30 15:48:09 +02:00
parent a8ee1edaf0
commit 524242bbdb
4 changed files with 0 additions and 70 deletions

View file

@ -14,8 +14,3 @@ STRIPE_SECRET_KEY=sk_test_...
STRIPE_WEBHOOK_SECRET=whsec_...
STRIPE_PRICE_ID=price_...
# Trello (for OpenCode MCP integration)
# API Key: https://trello.com/app-key
# Token: https://trello.com/1/authorize?expiration=never&name=BilHej&scope=read,write&response_type=token&key=YOUR_API_KEY
TRELLO_API_KEY=
TRELLO_TOKEN=

View file

@ -191,18 +191,6 @@ public vehicle info) must be excluded from the Spring Security filter chain.
---
## Task Tracking
Project tasks live in Trello (imported from `trello-import.csv`).
Before starting work, use the `trello` tool to check the board for the next
pending card in priority order. When a task is complete, move its card to a
"Done" list.
Trello integration is configured via MCP in `opencode.json`. Requires
`TRELLO_API_KEY` and `TRELLO_TOKEN` env vars (see `.env.example`).
---
## External References
For detailed conventions, load `@CODING_GUIDELINES.md`.

View file

@ -4,16 +4,5 @@
"permission": {
"edit": "ask",
"bash": "ask"
},
"mcp": {
"trello": {
"type": "local",
"command": ["npx", "-y", "@delorenj/mcp-server-trello"],
"environment": {
"TRELLO_API_KEY": "{env:TRELLO_API_KEY}",
"TRELLO_TOKEN": "{env:TRELLO_TOKEN}"
},
"enabled": true
}
}
}

View file

@ -1,42 +0,0 @@
Card Name,Description,List,Labels
Scaffold Vue 3 + Vite project,"Run `npm create vue@latest` or `npm create vite@latest` with Vue template. Verify `npm run dev` serves blank page on port 3000.",Infra & Scaffolding,Frontend
Scaffold Spring Boot 3 project,"Generate via Spring Initializr with dependencies: Spring Web, Spring Security, Spring Data JPA, PostgreSQL Driver, Flyway, Validation, Lombok. Verify `./mvnw spring-boot:run` starts on port 8080.",Infra & Scaffolding,Backend
Docker Compose setup,"Create `docker-compose.yml` with 3 services: postgres (16), backend (Java 21), frontend (Node/Vite dev mode). Verify `docker compose up` starts all 3 services successfully.",Infra & Scaffolding,DevOps
.env.example + env config,"Create `.env.example` with all required vars: POSTGRES_DB, POSTGRES_USER, POSTGRES_PASSWORD, JWT_SECRET, STRIPE_SECRET_KEY, STRIPE_WEBHOOK_SECRET, STRIPE_PRICE_ID. Wire backend and docker-compose to read from `.env`.",Infra & Scaffolding,DevOps
Flyway + initial migration,"Add Flyway dependency and config to Spring Boot. Create first migration file `V1__create_users_table.sql`. Verify migration runs automatically on startup and table exists in DB.",Infra & Scaffolding,Backend
Initial DB schema,"Write Flyway migrations for all core tables: users, orders, templates, blocklist, audit_log. All migrations run on startup. Tables exist and match the schema from REQUIREMENTS.md.",Infra & Scaffolding,Backend
User entity + repo + service,"Create JPA entity `User` (id UUID PK, email unique, password_hash, created_at, subscription enum). Create Spring Data repository. Create UserService with findByEmail and createUser methods.",Auth,Backend
JWT token generation + filter,"Create JwtUtil class (generate, validate, extract username). Create JwtAuthenticationFilter (OncePerRequestFilter, checks Authorization header). Configure SecurityFilterChain bean in SecurityConfig.",Auth,Backend
Register endpoint,"Create AuthController with POST /api/auth/register. Validate email format and password length. Hash password with BCrypt. Return JWT token. Return 409 on duplicate email.",Auth,Backend
Login endpoint,"Create POST /api/auth/login in AuthController. Authenticate credentials. Return JWT token on success. Return 401 on invalid credentials.",Auth,Backend
Register page,"Create RegisterPage.vue with email and password fields, validation, submit button. On success: store token via auth store, redirect to home. On error: show Swedish error message.",Auth,Frontend
Login page,"Create LoginPage.vue with email and password fields. On success: store token and redirect. On error: show ""Felaktig e-post eller lösenord"".",Auth,Frontend
Pinia auth store + API interceptor,"Create `stores/authStore.js` (token, user, login, logout, isAuthenticated). Create `api/client.js` (base URL, auto-attach Bearer token, handle 401 responses). Token persisted in localStorage.",Auth,Frontend
Vue Router auth guards,"Configure Vue Router with routes for home, login, register, compose, orders, admin. Add beforeEach guard: redirect to /login if route requires auth and user is not authenticated.",Auth,Frontend
Vehicle lookup controller,"Create VehicleController with GET /api/vehicles/{plate}. Validate plate format. Return mock/stub vehicle info (make, model, year, color) matching the plate. Create VehicleResponse DTO.",Vehicle Info,Backend
PlateInput component,"Create PlateInput.vue. Text input with auto-uppercase. Validate Swedish plate format (ABC123 or ABC12D) in real-time. Emit `lookup` event on valid submit. Show inline error on invalid format.",Vehicle Info,Frontend
Vehicle info display,"Create VehicleInfo.vue. Receives vehicle data as prop. Displays make, model, year, color in a clean card. Shows loading state while fetching. Shows ""Inget fordon hittades"" on lookup failure.",Vehicle Info,Frontend
Landing/home page,"Create HomePage.vue. Combines PlateInput and VehicleInfo. After successful lookup, shows ""Skicka ett brev till ägaren"" button that navigates to compose page with plate in query params.",Vehicle Info,Frontend
Template entity + seed data,"Create Template entity (id, name, body_template, is_active). Create Flyway migration for templates table. Create data.sql or Java seeder that inserts 5 default templates (Komplimang, Köpa, Tips, Körbeteende, Tuta).",Letter Composer,Backend
Templates API endpoint,"Create TemplateController with GET /api/templates. Return only active templates. Public endpoint (no auth required). Return TemplateResponse list (id, name, body_template).",Letter Composer,Frontend/Backend
Template selector,"Create TemplateSelector.vue. Dropdown/select listing templates fetched from API. Selecting one fills the editor with body_template text. Include ""Fritt meddelande"" option that leaves editor blank.",Letter Composer,Frontend
Letter editor,"Create LetterEditor.vue. Textarea with live character counter (e.g. ""247/1000""). Enforce 1000 char max. Editable even when template is selected. Emit content on change.",Letter Composer,Frontend
Letter preview,"Create LetterPreview.vue. Receives letter text as prop. Renders text styled as A4 letter (white background, letter layout, preview of what recipient sees).",Letter Composer,Frontend
Compose page,"Create ComposePage.vue. Combined flow: template selector → letter editor → letter preview. Read plate from route query. ""Skicka brev"" button at bottom triggers order creation.",Letter Composer,Frontend
Order entity + repo + service,"Create Order entity (id UUID, user_id FK, plate, template, letter_text, status enum, amount_paid, tracking_id, timestamps). Create repository. Create OrderService with createOrder method (status: pending_payment).",Orders & Payment,Backend
Create order endpoint,"Create OrderController with POST /api/orders (auth required). Accept CreateOrderRequest (plate, template, letter_text). Validate plate format, text length. Return OrderResponse with order ID and status.",Orders & Payment,Backend
Stripe config + checkout session,"Create StripeConfig (@ConfigurationProperties). Create PaymentService.createCheckoutSession(orderId). Call Stripe API to create session with product price. Return session URL. Store session ID on order.",Orders & Payment,Backend
Stripe webhook handler,"Create WebhookController with POST /api/webhooks/stripe (no auth, verify Stripe signature). Handle checkout.session.completed: mark order as paid. Log all events for debugging.",Orders & Payment,Backend
Payment trigger flow,"In ComposePage: ""Skicka brev"" → POST /api/orders (backend returns order with checkout URL) → redirect window to Stripe. Create PaymentRedirect.vue that extracts order data and redirects.",Orders & Payment,Frontend
Payment success page,"Create SuccessPage.vue shown after Stripe redirect. Receives session_id in query. Shows confirmation: ""Ditt brev är på väg!"". Shows order summary (plate, template). Links to order history.",Orders & Payment,Frontend
Order history page,"Create OrderHistoryPage.vue (auth required). Fetches GET /api/orders. Renders table/card list with: date, plate, template name, status badge (Sent/På väg/Delivered), tracking link if available.",Orders & Payment,Frontend
Admin order list endpoint,"Create AdminController with GET /api/admin/orders (admin auth). Returns all orders sorted by created_at DESC. Include user email in response. Admin-only via @PreAuthorize or role check.",Admin Panel,Backend
Admin status update endpoint,"Create PATCH /api/admin/orders/{id}/status in AdminController. Accept status string. Validate status enum values. Update order status and timestamp. Return updated order.",Admin Panel,Backend
Admin login page,"Create AdminLoginPage.vue separate from user login. Hardcoded admin credentials (MVP only — move to DB later). Store admin token separately in localStorage.",Admin Panel,Frontend
Admin dashboard,"Create AdminDashboard.vue (admin auth guard). Table of all orders with columns: date, user email, plate, template, status badge. Click row to expand letter content. Status dropdown to update order status.",Admin Panel,Frontend
Manual tracking entry,"In admin dashboard: editable tracking_id field per order. On save: PATCH /api/admin/orders/{id} with new tracking_id. Add PostNord tracking link helper (https://www.postnord.se/spara?id=...).",Admin Panel,Frontend
Backend Dockerfile,"Multi-stage Dockerfile: build stage (maven, compile), run stage (eclipse-temurin:21-jre-alpine, non-root user). Copy JAR. Entrypoint: java -jar. Expose 8080.",Deployment,DevOps
Frontend Dockerfile,"Multi-stage Dockerfile: build stage (node:20-alpine, npm ci, npm run build), run stage (nginx:alpine, copy dist to /usr/share/nginx/html). Include nginx.conf or rely on compose-provided nginx.",Deployment,DevOps
Nginx reverse proxy config,"Create nginx.conf that routes /api/* to backend:8080 and everything else to frontend static files. Add CORS headers. Enable gzip. Ready for production proxying.",Deployment,DevOps
Production Compose file,"Create docker-compose.prod.yml. Same services but: frontend serves built files via nginx internally, nginx reverse proxy handles SSL termination with cert volumes, PostgreSQL uses named volume for persistence.",Deployment,DevOps
Deploy to home server,"Copy repo and .env to host. Run `docker compose -f docker-compose.prod.yml up -d`. Configure dyndns if needed. Set up Certbot/LetsEncrypt cron for SSL renewal. Verify HTTPS access from external network.",Deployment,DevOps
1 Card Name Description List Labels
2 Scaffold Vue 3 + Vite project Run `npm create vue@latest` or `npm create vite@latest` with Vue template. Verify `npm run dev` serves blank page on port 3000. Infra & Scaffolding Frontend
3 Scaffold Spring Boot 3 project Generate via Spring Initializr with dependencies: Spring Web, Spring Security, Spring Data JPA, PostgreSQL Driver, Flyway, Validation, Lombok. Verify `./mvnw spring-boot:run` starts on port 8080. Infra & Scaffolding Backend
4 Docker Compose setup Create `docker-compose.yml` with 3 services: postgres (16), backend (Java 21), frontend (Node/Vite dev mode). Verify `docker compose up` starts all 3 services successfully. Infra & Scaffolding DevOps
5 .env.example + env config Create `.env.example` with all required vars: POSTGRES_DB, POSTGRES_USER, POSTGRES_PASSWORD, JWT_SECRET, STRIPE_SECRET_KEY, STRIPE_WEBHOOK_SECRET, STRIPE_PRICE_ID. Wire backend and docker-compose to read from `.env`. Infra & Scaffolding DevOps
6 Flyway + initial migration Add Flyway dependency and config to Spring Boot. Create first migration file `V1__create_users_table.sql`. Verify migration runs automatically on startup and table exists in DB. Infra & Scaffolding Backend
7 Initial DB schema Write Flyway migrations for all core tables: users, orders, templates, blocklist, audit_log. All migrations run on startup. Tables exist and match the schema from REQUIREMENTS.md. Infra & Scaffolding Backend
8 User entity + repo + service Create JPA entity `User` (id UUID PK, email unique, password_hash, created_at, subscription enum). Create Spring Data repository. Create UserService with findByEmail and createUser methods. Auth Backend
9 JWT token generation + filter Create JwtUtil class (generate, validate, extract username). Create JwtAuthenticationFilter (OncePerRequestFilter, checks Authorization header). Configure SecurityFilterChain bean in SecurityConfig. Auth Backend
10 Register endpoint Create AuthController with POST /api/auth/register. Validate email format and password length. Hash password with BCrypt. Return JWT token. Return 409 on duplicate email. Auth Backend
11 Login endpoint Create POST /api/auth/login in AuthController. Authenticate credentials. Return JWT token on success. Return 401 on invalid credentials. Auth Backend
12 Register page Create RegisterPage.vue with email and password fields, validation, submit button. On success: store token via auth store, redirect to home. On error: show Swedish error message. Auth Frontend
13 Login page Create LoginPage.vue with email and password fields. On success: store token and redirect. On error: show "Felaktig e-post eller lösenord". Auth Frontend
14 Pinia auth store + API interceptor Create `stores/authStore.js` (token, user, login, logout, isAuthenticated). Create `api/client.js` (base URL, auto-attach Bearer token, handle 401 responses). Token persisted in localStorage. Auth Frontend
15 Vue Router auth guards Configure Vue Router with routes for home, login, register, compose, orders, admin. Add beforeEach guard: redirect to /login if route requires auth and user is not authenticated. Auth Frontend
16 Vehicle lookup controller Create VehicleController with GET /api/vehicles/{plate}. Validate plate format. Return mock/stub vehicle info (make, model, year, color) matching the plate. Create VehicleResponse DTO. Vehicle Info Backend
17 PlateInput component Create PlateInput.vue. Text input with auto-uppercase. Validate Swedish plate format (ABC123 or ABC12D) in real-time. Emit `lookup` event on valid submit. Show inline error on invalid format. Vehicle Info Frontend
18 Vehicle info display Create VehicleInfo.vue. Receives vehicle data as prop. Displays make, model, year, color in a clean card. Shows loading state while fetching. Shows "Inget fordon hittades" on lookup failure. Vehicle Info Frontend
19 Landing/home page Create HomePage.vue. Combines PlateInput and VehicleInfo. After successful lookup, shows "Skicka ett brev till ägaren" button that navigates to compose page with plate in query params. Vehicle Info Frontend
20 Template entity + seed data Create Template entity (id, name, body_template, is_active). Create Flyway migration for templates table. Create data.sql or Java seeder that inserts 5 default templates (Komplimang, Köpa, Tips, Körbeteende, Tuta). Letter Composer Backend
21 Templates API endpoint Create TemplateController with GET /api/templates. Return only active templates. Public endpoint (no auth required). Return TemplateResponse list (id, name, body_template). Letter Composer Frontend/Backend
22 Template selector Create TemplateSelector.vue. Dropdown/select listing templates fetched from API. Selecting one fills the editor with body_template text. Include "Fritt meddelande" option that leaves editor blank. Letter Composer Frontend
23 Letter editor Create LetterEditor.vue. Textarea with live character counter (e.g. "247/1000"). Enforce 1000 char max. Editable even when template is selected. Emit content on change. Letter Composer Frontend
24 Letter preview Create LetterPreview.vue. Receives letter text as prop. Renders text styled as A4 letter (white background, letter layout, preview of what recipient sees). Letter Composer Frontend
25 Compose page Create ComposePage.vue. Combined flow: template selector → letter editor → letter preview. Read plate from route query. "Skicka brev" button at bottom triggers order creation. Letter Composer Frontend
26 Order entity + repo + service Create Order entity (id UUID, user_id FK, plate, template, letter_text, status enum, amount_paid, tracking_id, timestamps). Create repository. Create OrderService with createOrder method (status: pending_payment). Orders & Payment Backend
27 Create order endpoint Create OrderController with POST /api/orders (auth required). Accept CreateOrderRequest (plate, template, letter_text). Validate plate format, text length. Return OrderResponse with order ID and status. Orders & Payment Backend
28 Stripe config + checkout session Create StripeConfig (@ConfigurationProperties). Create PaymentService.createCheckoutSession(orderId). Call Stripe API to create session with product price. Return session URL. Store session ID on order. Orders & Payment Backend
29 Stripe webhook handler Create WebhookController with POST /api/webhooks/stripe (no auth, verify Stripe signature). Handle checkout.session.completed: mark order as paid. Log all events for debugging. Orders & Payment Backend
30 Payment trigger flow In ComposePage: "Skicka brev" → POST /api/orders (backend returns order with checkout URL) → redirect window to Stripe. Create PaymentRedirect.vue that extracts order data and redirects. Orders & Payment Frontend
31 Payment success page Create SuccessPage.vue shown after Stripe redirect. Receives session_id in query. Shows confirmation: "Ditt brev är på väg!". Shows order summary (plate, template). Links to order history. Orders & Payment Frontend
32 Order history page Create OrderHistoryPage.vue (auth required). Fetches GET /api/orders. Renders table/card list with: date, plate, template name, status badge (Sent/På väg/Delivered), tracking link if available. Orders & Payment Frontend
33 Admin order list endpoint Create AdminController with GET /api/admin/orders (admin auth). Returns all orders sorted by created_at DESC. Include user email in response. Admin-only via @PreAuthorize or role check. Admin Panel Backend
34 Admin status update endpoint Create PATCH /api/admin/orders/{id}/status in AdminController. Accept status string. Validate status enum values. Update order status and timestamp. Return updated order. Admin Panel Backend
35 Admin login page Create AdminLoginPage.vue separate from user login. Hardcoded admin credentials (MVP only — move to DB later). Store admin token separately in localStorage. Admin Panel Frontend
36 Admin dashboard Create AdminDashboard.vue (admin auth guard). Table of all orders with columns: date, user email, plate, template, status badge. Click row to expand letter content. Status dropdown to update order status. Admin Panel Frontend
37 Manual tracking entry In admin dashboard: editable tracking_id field per order. On save: PATCH /api/admin/orders/{id} with new tracking_id. Add PostNord tracking link helper (https://www.postnord.se/spara?id=...). Admin Panel Frontend
38 Backend Dockerfile Multi-stage Dockerfile: build stage (maven, compile), run stage (eclipse-temurin:21-jre-alpine, non-root user). Copy JAR. Entrypoint: java -jar. Expose 8080. Deployment DevOps
39 Frontend Dockerfile Multi-stage Dockerfile: build stage (node:20-alpine, npm ci, npm run build), run stage (nginx:alpine, copy dist to /usr/share/nginx/html). Include nginx.conf or rely on compose-provided nginx. Deployment DevOps
40 Nginx reverse proxy config Create nginx.conf that routes /api/* to backend:8080 and everything else to frontend static files. Add CORS headers. Enable gzip. Ready for production proxying. Deployment DevOps
41 Production Compose file Create docker-compose.prod.yml. Same services but: frontend serves built files via nginx internally, nginx reverse proxy handles SSL termination with cert volumes, PostgreSQL uses named volume for persistence. Deployment DevOps
42 Deploy to home server Copy repo and .env to host. Run `docker compose -f docker-compose.prod.yml up -d`. Configure dyndns if needed. Set up Certbot/LetsEncrypt cron for SSL renewal. Verify HTTPS access from external network. Deployment DevOps