feat: implement Iteration 0 foundation (backend + Flutter client)
Backend (Go): - Project structure with chi router, pgxpool, goose migrations - JWT auth (access/refresh tokens) with Firebase token verification - NoopTokenVerifier for local dev without Firebase credentials - PostgreSQL user repository with atomic profile updates (transactions) - Mifflin-St Jeor calorie calculation based on profile data - REST API: POST /auth/login, /auth/refresh, /auth/logout, GET/PUT /profile, GET /health - Middleware: auth, CORS (localhost wildcard), logging, recovery, request_id - Unit tests (51 passing) and integration tests (testcontainers) - Docker Compose setup with postgres healthcheck and graceful shutdown Flutter client: - Riverpod state management with GoRouter navigation - Firebase Auth (email/password + Google sign-in with web popup support) - Platform-aware API URLs (web/Android/iOS) - Dio HTTP client with JWT auth interceptor and concurrent refresh handling - Secure token storage - Screens: Login, Register, Home (tabs: Menu, Recipes, Products, Profile) - Unit tests (17 passing) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
49
backend/migrations/001_create_users.sql
Normal file
49
backend/migrations/001_create_users.sql
Normal file
@@ -0,0 +1,49 @@
|
||||
-- +goose Up
|
||||
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
|
||||
|
||||
CREATE TYPE user_plan AS ENUM ('free', 'paid');
|
||||
CREATE TYPE user_gender AS ENUM ('male', 'female');
|
||||
CREATE TYPE user_goal AS ENUM ('lose', 'maintain', 'gain');
|
||||
CREATE TYPE activity_level AS ENUM ('low', 'moderate', 'high');
|
||||
|
||||
CREATE TABLE users (
|
||||
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
|
||||
firebase_uid VARCHAR(128) NOT NULL UNIQUE,
|
||||
email VARCHAR(255) NOT NULL,
|
||||
name VARCHAR(255) NOT NULL DEFAULT '',
|
||||
avatar_url TEXT,
|
||||
|
||||
-- Body parameters
|
||||
height_cm SMALLINT,
|
||||
weight_kg DECIMAL(5,2),
|
||||
age SMALLINT,
|
||||
gender user_gender,
|
||||
activity activity_level,
|
||||
|
||||
-- Goal and calculated daily norm
|
||||
goal user_goal,
|
||||
daily_calories INTEGER,
|
||||
|
||||
-- Plan
|
||||
plan user_plan NOT NULL DEFAULT 'free',
|
||||
|
||||
-- Preferences (JSONB for flexibility)
|
||||
preferences JSONB NOT NULL DEFAULT '{}'::jsonb,
|
||||
|
||||
-- Refresh token
|
||||
refresh_token TEXT,
|
||||
token_expires_at TIMESTAMPTZ,
|
||||
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT now()
|
||||
);
|
||||
|
||||
CREATE INDEX idx_users_firebase_uid ON users (firebase_uid);
|
||||
CREATE INDEX idx_users_email ON users (email);
|
||||
|
||||
-- +goose Down
|
||||
DROP TABLE IF EXISTS users;
|
||||
DROP TYPE IF EXISTS activity_level;
|
||||
DROP TYPE IF EXISTS user_goal;
|
||||
DROP TYPE IF EXISTS user_gender;
|
||||
DROP TYPE IF EXISTS user_plan;
|
||||
Reference in New Issue
Block a user