a6c03a091e
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)
122 lines
3.6 KiB
TypeScript
122 lines
3.6 KiB
TypeScript
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;
|
|
}
|