initial: split from gov-agreg — vreau.digital standalone platform
Moved from gov-agreg/src/pages/achizitii/* to root (drop prefix). - 22 pages migrated, 127 files total - All internal links: /achizitii/X → /X (176 occurrences fixed) - AchizitiiLayout subnav rewritten: /X paths, top-right link to vreaudigital.ro hub - BaseLayout new (vreau.digital branding, OG tags, site URL) - astro.config.mjs: site https://vreau.digital, server output (was static) - docker-compose: port 5096 (vreaudigital is 5095), container vreau-digital - deploy.sh: paths /opt/vreau-digital, log /var/log/vreau-digital-deploy.log Backend shared with gov-agreg: - PostgreSQL satra (same schemas: seap, firms, anaf, anre, ...) - Photon, Martin tiles - Infisical /vreaudigital path (DATABASE_URL etc. shared) build: PASS (npx astro check 0 errors, npm run build 5s vite + 10s server)
This commit is contained in:
@@ -0,0 +1,121 @@
|
||||
import { query } from './db.js';
|
||||
|
||||
export interface UserProfile {
|
||||
id: string;
|
||||
email: string;
|
||||
name: string | null;
|
||||
city: string | null;
|
||||
role: 'user' | 'developer' | 'admin';
|
||||
bio: string | null;
|
||||
github_url: string | null;
|
||||
website_url: string | null;
|
||||
created_at: string;
|
||||
}
|
||||
|
||||
export async function ensureAuthTables() {
|
||||
await query(`
|
||||
CREATE SCHEMA IF NOT EXISTS platform;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS platform.user_profiles (
|
||||
id TEXT PRIMARY KEY,
|
||||
email TEXT UNIQUE NOT NULL,
|
||||
name TEXT,
|
||||
city TEXT,
|
||||
role TEXT DEFAULT 'user' CHECK (role IN ('user', 'developer', 'admin')),
|
||||
bio TEXT,
|
||||
github_url TEXT,
|
||||
website_url TEXT,
|
||||
created_at TIMESTAMPTZ DEFAULT NOW()
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS platform.product_submissions (
|
||||
id SERIAL PRIMARY KEY,
|
||||
user_id TEXT REFERENCES platform.user_profiles(id),
|
||||
title TEXT NOT NULL,
|
||||
description TEXT NOT NULL,
|
||||
category TEXT NOT NULL,
|
||||
demo_url TEXT,
|
||||
source_url TEXT,
|
||||
screenshot_url TEXT,
|
||||
status TEXT DEFAULT 'pending' CHECK (status IN ('pending', 'approved', 'rejected')),
|
||||
solves_ideas INTEGER[] DEFAULT '{}',
|
||||
created_at TIMESTAMPTZ DEFAULT NOW()
|
||||
);
|
||||
|
||||
-- Add solves_product column to ideas if not exists
|
||||
DO $$ BEGIN
|
||||
ALTER TABLE platform.ideas ADD COLUMN IF NOT EXISTS solved_by_product TEXT;
|
||||
ALTER TABLE platform.ideas ADD COLUMN IF NOT EXISTS vote_threshold_reached BOOLEAN DEFAULT FALSE;
|
||||
EXCEPTION WHEN OTHERS THEN NULL;
|
||||
END $$;
|
||||
`);
|
||||
}
|
||||
|
||||
export async function getOrCreateProfile(id: string, email: string): Promise<UserProfile> {
|
||||
const existing = await query<UserProfile>(
|
||||
'SELECT * FROM platform.user_profiles WHERE id = $1', [id]
|
||||
);
|
||||
if (existing.rows[0]) return existing.rows[0];
|
||||
|
||||
const result = await query<UserProfile>(
|
||||
`INSERT INTO platform.user_profiles (id, email) VALUES ($1, $2) RETURNING *`,
|
||||
[id, email]
|
||||
);
|
||||
return result.rows[0];
|
||||
}
|
||||
|
||||
export async function updateProfile(id: string, data: {
|
||||
name?: string;
|
||||
city?: string;
|
||||
bio?: string;
|
||||
github_url?: string;
|
||||
website_url?: string;
|
||||
}): Promise<UserProfile> {
|
||||
const result = await query<UserProfile>(
|
||||
`UPDATE platform.user_profiles
|
||||
SET name = COALESCE($2, name),
|
||||
city = COALESCE($3, city),
|
||||
bio = COALESCE($4, bio),
|
||||
github_url = COALESCE($5, github_url),
|
||||
website_url = COALESCE($6, website_url)
|
||||
WHERE id = $1 RETURNING *`,
|
||||
[id, data.name, data.city, data.bio, data.github_url, data.website_url]
|
||||
);
|
||||
return result.rows[0];
|
||||
}
|
||||
|
||||
export async function submitProduct(data: {
|
||||
user_id: string;
|
||||
title: string;
|
||||
description: string;
|
||||
category: string;
|
||||
demo_url?: string;
|
||||
source_url?: string;
|
||||
screenshot_url?: string;
|
||||
solves_ideas?: number[];
|
||||
}) {
|
||||
const result = await query(
|
||||
`INSERT INTO platform.product_submissions
|
||||
(user_id, title, description, category, demo_url, source_url, screenshot_url, solves_ideas)
|
||||
VALUES ($1, $2, $3, $4, $5, $6, $7, $8) RETURNING id`,
|
||||
[data.user_id, data.title, data.description, data.category,
|
||||
data.demo_url || null, data.source_url || null, data.screenshot_url || null,
|
||||
data.solves_ideas || []]
|
||||
);
|
||||
return result.rows[0].id;
|
||||
}
|
||||
|
||||
export async function getUserSubmissions(userId: string) {
|
||||
const result = await query(
|
||||
'SELECT * FROM platform.product_submissions WHERE user_id = $1 ORDER BY created_at DESC',
|
||||
[userId]
|
||||
);
|
||||
return result.rows;
|
||||
}
|
||||
|
||||
export async function getProfile(id: string): Promise<UserProfile | null> {
|
||||
const result = await query<UserProfile>(
|
||||
'SELECT * FROM platform.user_profiles WHERE id = $1', [id]
|
||||
);
|
||||
return result.rows[0] || null;
|
||||
}
|
||||
Reference in New Issue
Block a user