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:
Claude VM
2026-05-13 00:10:32 +03:00
commit a6c03a091e
352 changed files with 75295 additions and 0 deletions
+121
View File
@@ -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;
}