feat: update roadmap with Poyraz UI design system; enhance database schema for safety and idempotency; add usage guide for Poyraz UI; include new images and remove outdated logo

This commit is contained in:
Poyraz Avsever
2026-06-02 12:20:42 +03:00
parent c0d25a87e8
commit b6b6f4fc32
17 changed files with 622 additions and 93 deletions
+61 -1
View File
@@ -353,12 +353,26 @@ Asagidaki ozellikler ilk surume alinmayacak:
### Onerilen MVP Stack ### Onerilen MVP Stack
- **Frontend:** Next.js App Router, React, TypeScript - **Frontend:** Next.js App Router, React, TypeScript
- **UI:** Tailwind CSS, shadcn/Radix, Recharts, Framer Motion - **UI:** Poyraz UI, Tailwind CSS v4, Recharts
- **Database:** PostgreSQL - **Database:** PostgreSQL
- **Backend/Auth:** Supabase veya self-host edilebilir Supabase alternatifi - **Backend/Auth:** Supabase veya self-host edilebilir Supabase alternatifi
- **Local AI opsiyonu:** Ollama - **Local AI opsiyonu:** Ollama
- **Cloud AI opsiyonlari:** OpenAI, Gemini, Groq - **Cloud AI opsiyonlari:** OpenAI, Gemini, Groq
### UI Karari
MVP tasarimi Poyraz UI ile light design olarak kurulacak.
Mevcut dark shadcn/Radix agirlikli prototip tasarim sistemi MVP icin referans alinmayacak. Sayfalar Poyraz UI bilesenleri, `poyraz-ui/preset.css` token sistemi ve Poyraz UI semantic renkleri uzerinden yeniden insa edilecek.
Gecis prensipleri:
- Ilk hedef login, register ve sidebar gibi uygulama kabugu ekranlari.
- Daha sonra Faz 2'de her modul kendi CRUD akisi gelistirilirken Poyraz UI'a tasinacak.
- Light design varsayilan olacak.
- Dark mode MVP icin zorunlu degil; Poyraz UI destekledigi icin sonraki fazlarda eklenebilir.
- Eski UI bilesenleri sadece gecici olarak kullanilabilir; yeni sayfa ve moduller Poyraz UI ile yazilacak.
### Neden Server-first? ### Neden Server-first?
Mobil uygulama sonraki hedef oldugu icin verinin senkronize olabilecegi merkezi bir backend gerekir. Bu nedenle MVP'de ana kaynak PostgreSQL/Supabase olmali. Mobil uygulama sonraki hedef oldugu icin verinin senkronize olabilecegi merkezi bir backend gerekir. Bu nedenle MVP'de ana kaynak PostgreSQL/Supabase olmali.
@@ -460,6 +474,39 @@ Not: SQL dosyalari repo icinde hazirdir. Supabase ortaminda calistirildiktan son
--- ---
### Faz 1.5: Poyraz UI Tasarim Sistemi Gecisi
Amac: Mevcut koyu prototip tasarimindan ayrilip uygulama kabugunu Poyraz UI tabanli light design sistemine tasimak.
Isler:
- `poyraz-ui` paketini projeye eklemek.
- Global CSS icinde Poyraz UI preset importunu yapmak: `@import "poyraz-ui/preset.css";`
- Tailwind CSS v4 gereksinimini ve mevcut Tailwind yapisiyla uyumlulugu netlestirmek.
- Poyraz UI light tokenlarini varsayilan tasarim dili olarak ayarlamak.
- Mevcut shadcn/Radix agirlikli dark auth tasarimini Poyraz UI ile degistirmek.
- Login sayfasini Poyraz UI atoms/molecules ile yeniden kurmak.
- Register sayfasini Poyraz UI atoms/molecules ile yeniden kurmak.
- Dashboard shell ve sidebar'i Poyraz UI navigation/organism yaklasimina gore yeniden kurmak.
- Eski dark background, gradient, glow ve agir motion desenlerini uygulama kabugundan kaldirmak.
- Poyraz UI kullanim notlarini proje dokumantasyonuna baglamak.
Kabul kriteri:
- Login light design ile Poyraz UI bilesenleri kullanarak calisir.
- Register light design ile Poyraz UI bilesenleri kullanarak calisir.
- Sidebar ve temel dashboard shell Poyraz UI tasarim diliyle uyumludur.
- Uygulama varsayilan olarak light gorunur.
- `npm run build` basarili olur.
Notlar:
- Bu fazda modul ic sayfalarinin tamamini yeniden tasarlamak zorunlu degildir.
- Modul sayfalari Faz 2'de CRUD gelistirme sirasinda Poyraz UI'a tasinir.
- Poyraz UI rehberi: `poyraz-ui-usage-guide.md`
---
### Faz 2: Core CRUD Modulleri ### Faz 2: Core CRUD Modulleri
Amac: Freelancer'in temel operasyon verilerini girebilmesi. Amac: Freelancer'in temel operasyon verilerini girebilmesi.
@@ -467,17 +514,30 @@ Amac: Freelancer'in temel operasyon verilerini girebilmesi.
Isler: Isler:
- Musteriler CRUD - Musteriler CRUD
- Liste, bos durum, ekleme/duzenleme formu ve detay gorunumu Poyraz UI ile kurulur.
- Eski CRM/prototip gorsel dili kaldirilir.
- Projeler/side project CRUD - Projeler/side project CRUD
- Proje kartlari, filtreler, detay paneli ve form akislari Poyraz UI ile kurulur.
- Musteri projesi ve side project ayrimi UI'da net gosterilir.
- Gorevler CRUD - Gorevler CRUD
- Liste ve basit kanban Poyraz UI bilesenleriyle yeniden tasarlanir.
- Durum, oncelik, deadline ve proje iliskisi icin Poyraz UI Badge/Form/Select kullanilir.
- Takvim etkinlikleri CRUD - Takvim etkinlikleri CRUD
- Aylik gorunum ve yaklasan etkinlik listesi light design ile kurulur.
- Etkinlik formu Poyraz UI form bilesenleriyle yazilir.
- Finans islemleri CRUD - Finans islemleri CRUD
- Gelir/gider listesi, finans kartlari ve islem formu Poyraz UI ile kurulur.
- Rapor kartlari Poyraz UI StatsCard/Card yaklasimina uygun olur.
- Daily mood/energy CRUD - Daily mood/energy CRUD
- Gunluk kayit formu, trend ozeti ve kayit listesi Poyraz UI ile kurulur.
- Mood/energy secimleri light, sade ve form odakli olur.
Kabul kriteri: Kabul kriteri:
- Mock data yerine gercek veriler kullanilir. - Mock data yerine gercek veriler kullanilir.
- Her modulde liste, ekleme, duzenleme ve temel silme/arsivleme vardir. - Her modulde liste, ekleme, duzenleme ve temel silme/arsivleme vardir.
- Bos durumlar kullaniciyi dogru aksiyona yonlendirir. - Bos durumlar kullaniciyi dogru aksiyona yonlendirir.
- Faz 2 kapsamindaki her yeni/yenilenen modul Poyraz UI bilesenleriyle yazilir.
--- ---
BIN
View File
Binary file not shown.

Before

Width:  |  Height:  |  Size: 149 KiB

After

Width:  |  Height:  |  Size: 56 KiB

+11 -2
View File
@@ -45,7 +45,16 @@ The existing `journals` table can either be migrated into `daily_logs` or kept a
## Execution Notes ## Execution Notes
This file should be treated as the first baseline. If it has already been run in a Supabase project, do not rerun it blindly because some `create table` and `create policy` statements are not idempotent. This file should be treated as the first baseline.
It was updated to be safer for Supabase SQL Editor retries:
- tables use `create table if not exists`
- policies are dropped before being recreated
- the profile trigger is dropped before being recreated
- the PL/pgSQL function uses the correct `$$` delimiter
- profile creation uses `on conflict (id) do nothing`
If a previous run failed halfway through, rerunning this baseline should be safe for the current schema shape.
Future changes should be added as ordered migration files rather than editing this baseline after execution. Future changes should be added as ordered migration files rather than editing this baseline after execution.
+1 -1
View File
@@ -1,6 +1,6 @@
/// <reference types="next" /> /// <reference types="next" />
/// <reference types="next/image-types/global" /> /// <reference types="next/image-types/global" />
import "./.next/types/routes.d.ts"; import "./.next/dev/types/routes.d.ts";
// NOTE: This file should not be edited // NOTE: This file should not be edited
// see https://nextjs.org/docs/app/api-reference/config/typescript for more information. // see https://nextjs.org/docs/app/api-reference/config/typescript for more information.
+413
View File
@@ -0,0 +1,413 @@
# Poyraz UI - Usage Guide (Detayli)
Bu dokuman, `d:/Poyraz/kodlama/poyraz-ui` reposunun guncel kaynak kodu uzerinden hazirlandi.
Hedef: UI kitin hem kullanici (consumer) tarafini hem de bu repoyu gelistirme tarafini tek yerde toplamak.
Versiyon referansi: `2.0.1`
---
## 1) Proje Ozeti
Poyraz UI, React tabanli, Tailwind CSS v4 ile calisan, atomic design yaklasimi kullanan bir UI kit.
Repo iki ana amaca hizmet ediyor:
1. npm paketi olarak dagitilan UI kutuphanesi (`src`, `components/ui`, `dist`)
2. Next.js App Router ile yazilmis canli dokumantasyon sitesi (`app`)
Temel karakter:
- clean border odakli, minimum shadow
- `rounded-sm` kullanimina dayali yalin gorunum
- semantic token sistemi (`--poyraz-*`)
- dark mode uyumlu
- atoms -> molecules -> organisms katmanlamasi
---
## 2) Dizin Yapisi (Gercek Kod Yapisi)
```txt
poyraz-ui/
|- app/ # Next.js docs sitesi
| |- docs/ # component/template dokumantasyon sayfalari
| |- globals.css # docs sitesi global css + dark override
| |- layout.tsx # next-themes + Toaster entegrasyonu
| `- page.tsx # landing/showcase
|- bin/
| `- cli.mjs # npx poyraz-ui init
|- components/
| |- ui/
| | |- atoms/ # 17 atom dosyasi
| | |- molecules/ # 22 molecule dosyasi
| | `- organisms/ # 5 organism dosyasi
| |- theme-provider.tsx # docs sitesi next-themes wrapper
| `- theme-toggle.tsx # docs sitesi toggle
|- lib/
| `- navigation.ts # docs nav/registry merkezi config
|- src/
| |- index.ts # ana export
| |- atoms/index.ts # atom export map
| |- molecules/index.ts # molecule export map
| |- organisms/index.ts # organism export map
| |- themes/index.ts # poyrazLightTheme / poyrazDarkTheme
| |- preset.css # token layer + @theme bridge
| `- utils.ts # cn()
|- dist/ # tsup output (publish edilen paket)
|- tsup.config.ts # 5 entry point, esm+cjs, dts
`- package.json
```
---
## 3) Kullanici Tarafi Kurulum (Consumer App)
### 3.1 Paket kurulumu
```bash
pnpm add poyraz-ui
# veya
npm install poyraz-ui
# veya
yarn add poyraz-ui
```
### 3.2 Zorunlu peer dependencies
- `react >= 18`
- `react-dom >= 18`
- `tailwindcss >= 4`
Opsiyonel peer dependencies:
- `react-hook-form`, `@hookform/resolvers`, `zod` (Form molecule icin)
- `reactive-switcher` (hazir theme objectleriyle dinamik tema gecisi icin)
### 3.3 CSS import (kritik)
Root global stylesheet dosyana ekle:
```css
@import "tailwindcss";
@import "poyraz-ui/preset.css";
```
`preset.css` olmadan renk/font tokenlari dogru resolve edilmez.
### 3.4 Hemen kullanim
```tsx
import { Button, Card, CardContent } from "poyraz-ui/atoms";
export function Demo() {
return (
<Card>
<CardContent className="p-4">
<Button>Merhaba</Button>
</CardContent>
</Card>
);
}
```
---
## 4) Import Stratejisi ve Entry Pointler
Paket 5 entry point sunuyor:
- `poyraz-ui`
- `poyraz-ui/atoms`
- `poyraz-ui/molecules`
- `poyraz-ui/organisms`
- `poyraz-ui/themes`
Onerilen yaklasim:
- Uretim projelerinde alt path importlarini kullan (`/atoms`, `/molecules`, `/organisms`)
- Gecis surecinde hiz icin ana barrel (`poyraz-ui`) kullanabilirsin
Ornek:
```tsx
import { Button, Badge } from "poyraz-ui/atoms";
import { Dialog } from "poyraz-ui/molecules";
import { Navbar } from "poyraz-ui/organisms";
import { poyrazLightTheme, poyrazDarkTheme } from "poyraz-ui/themes";
```
---
## 5) Tema Sistemi (En Onemli Altyapi)
Tema zinciri su sekilde calisiyor:
1. Component classlari `bg-background`, `text-foreground`, `border-border` gibi semantic utility kullaniyor.
2. `src/preset.css`, `@theme` ile bunlari `--color-*` tokenlarina bagliyor.
3. `--color-*` tokenlari, `var(--poyraz-*, fallback)` ile semantic CSS variable'a mapleniyor.
4. Sen `--poyraz-*` degistirdiginde tum kit yeni temaya gecer.
### 5.1 Token katmanlari
- Base semantic variables: `--poyraz-background`, `--poyraz-foreground`, `--poyraz-primary`, ...
- Tailwind v4 bridge: `--color-background`, `--color-foreground`, ...
- Utility kullanim: `bg-background`, `text-muted-foreground`, ...
### 5.2 Dark mode (class tabanli)
Docs sitesi `next-themes` kullaniyor ve `html.dark` altinda `--poyraz-*` override ediyor (`app/globals.css`).
### 5.3 reactive-switcher entegrasyonu
`src/themes/index.ts` icinde hazir theme objectleri var:
- `poyrazLightTheme`
- `poyrazDarkTheme`
- `poyrazThemes`
Ornek:
```tsx
import { ThemeProvider } from "reactive-switcher";
import { poyrazThemes } from "poyraz-ui/themes";
export function AppTheme({ children }: { children: React.ReactNode }) {
return <ThemeProvider themes={poyrazThemes}>{children}</ThemeProvider>;
}
```
---
## 6) Component Katalogu
Bu bolum `src/*/index.ts` export maplerine gore hazirlandi.
### 6.1 Atoms (17 component dosyasi)
- Avatar
- Badge
- Button
- Card
- Checkbox
- Input
- Label
- Logo
- Radio Group
- Separator
- Skeleton
- Switch
- Textarea
- Typography
- Form Fields (`NumberInput`, `SearchInput`, `PhoneInput`, `PasswordInput`, `UrlInput`)
- BG Patterns (`PatternDots`, `PatternGrid`, `PatternLines`, `PatternDiagonal`, `PatternCross`, `PatternCheckerboard`, `PatternDiamond`, `PatternZigzag`, `PatternDashedGrid`, `PatternRadial`)
- ScrollArea
### 6.2 Molecules (22 component dosyasi)
Core molecules:
- Accordion
- Alert
- Autocomplete
- Breadcrumb
- Calendar
- Command Palette
- Date Picker
- Dialog
- Drawer
- Dropdown Menu
- Form
- Hover Card
- Modal
- Pagination
- Popover
- Select
- Sheet
- Sonner (`Toaster`, `toast`)
- Tabs
- Tooltip
Template molecules (card-templates):
- ArticleCard
- ImageCard
- NewsCard
- StatsCard
- TestimonialCard
- PricingCard
- ProductCard
### 6.3 Organisms (5 component dosyasi)
- Navbar
- Sidebar
- Footer
- AnnouncementBar
- DataTable
---
## 7) Hazir Template Sayfalari (Docs Icinde)
`app/docs/templates` altinda 4 kopyalanabilir sayfa semasi var:
- Hero
- Pricing
- Dashboard
- Auth
Onemli not:
- Bunlar npm paketi icinde "template component" olarak export edilmiyor.
- Kaynagi kopyalayip projenin ihtiyacina gore duzenleme modeli kullaniliyor.
---
## 8) Dokumantasyon Sitesi Mimarisi
`app/docs` altinda:
- toplam `53` adet `page.tsx`
- atoms: `18`
- molecules: `22`
- organisms: `6`
- templates: `5`
Merkezi nav/registry:
- `lib/navigation.ts`
- sidebardaki kategori sayilari ve slug donusumu burada yonetiliyor (`toSlug`)
---
## 9) CLI: `npx poyraz-ui init`
CLI (`bin/cli.mjs`) su adimlari yapar:
1. CSS dosyasini otomatik tespit eder (`app/globals.css`, `src/app/globals.css` vb.)
2. `@import "poyraz-ui/preset.css";` satirini ekler
3. Opsiyonel olarak `reactive-switcher` tema dosyasi scaffold eder
4. Layout icin ThemeProvider snippet'i gosterir
Manual kurulum yerine hizli onboarding icin ideal.
---
## 10) Build, Bundle ve Publish Akisi
### 10.1 Scriptler
- `pnpm dev`: docs sitesi
- `pnpm build`: library + docs production build
- `pnpm build:lib`: sadece library (`tsup`)
- `pnpm start`: next production serve
- `pnpm prepublishOnly`: publish oncesi otomatik `build:lib`
### 10.2 tsup ozeti
`tsup.config.ts`:
- 5 entry point uretir (`index`, `atoms/index`, `molecules/index`, `organisms/index`, `themes/index`)
- format: `esm + cjs`
- `dts: true`
- `splitting + treeshake + clean`
- build sonrasi `dist` dosyalarina `"use client"` directive inject eder
### 10.3 package export haritasi
`package.json` `exports` alani:
- alt path importlarini hem ESM hem CJS ile aciklar
- `./preset.css` dogrudan `src/preset.css`'e yonlenir
---
## 11) Bu Repoda Yeni Component Ekleme Rehberi
### 11.1 Kod ekleme
1. Component dosyasini `components/ui/<layer>/` altina ekle
2. Gerekirse type exportlarini component dosyasinda tanimla
### 11.2 Export haritasi
3. `src/<layer>/index.ts` icine export satirlarini ekle
4. Gerekliyse `src/index.ts` ana barrel kontrol et
### 11.3 Docs entegrasyonu
5. `app/docs/<layer>/<component>/page.tsx` olustur
6. Kategori index sayfasina link ekle (`app/docs/<layer>/page.tsx`)
7. `lib/navigation.ts` icindeki `componentRegistry` listesine ekle
### 11.4 Dogrulama
8. `pnpm build:lib`
9. `pnpm dev` ile docs sayfasini ve importlarini test et
---
## 12) Sik Kullanilan Kullanim Patternleri
### 12.1 Form stack
- Atoms: `Input`, `Label`, `Checkbox`, `Button`
- Molecules: `Form`, `Select`, `DatePicker`, `Autocomplete`
### 12.2 Overlay stack
- `Dialog`, `Modal`, `Drawer`, `Sheet`, `Popover`, `Tooltip`
- Her biri Radix/Vaul primitive uzerinden geldigi icin a11y ve keyboard destegi yuksek
### 12.3 Navigation stack
- `Navbar` (desktop + mobile panel)
- `Sidebar` (collapsible/floating/mini varyantlar)
- `Footer` (layout varyantlari)
### 12.4 Data stack
- `DataTable` + `Badge` + `Pagination`
- dashboard tarzinda `StatsCard`, `Card`, `Avatar` ile birlikte kullaniliyor
---
## 13) Bilinen Durumlar / Dikkat Noktalari
1. `Mermaid` dokumantasyon sayfasi var (`app/docs/molecules/mermaid/page.tsx`) ancak su anda `src/molecules/index.ts` icinden export edilmiyor.
2. `componentRegistry` molecules listesi ile molecules landing page listesi tam birebir degil (sidebar listesinde Mermaid yok).
3. Template sayfalari (Hero/Pricing/Dashboard/Auth) paket exportu degil; kopyala-ozellestir modeli.
4. Rehber ve README metinlerinde bilesen sayilari bazen farkli geciyor; son karar noktasi her zaman `src/*/index.ts` export mapidir.
---
## 14) Hizli Referans
### 14.1 Consumer app checklist
1. `poyraz-ui` paketini kur
2. `@import "poyraz-ui/preset.css";` ekle
3. `poyraz-ui/atoms` veya `poyraz-ui/molecules` uzerinden import et
4. Tema gerekiyorsa `--poyraz-*` override et veya `poyraz-ui/themes` kullan
### 14.2 Repo contributor checklist
1. component dosyasi ekle (`components/ui`)
2. export map guncelle (`src/*/index.ts`)
3. docs page ekle (`app/docs/...`)
4. navigation registry guncelle (`lib/navigation.ts`)
5. `pnpm build:lib` ve `pnpm dev` ile dogrula
---
## 15) Ek Kaynaklar
- Paket genel tanitim: `README.md`
- Genis API referansi: `COMPONENTS.md`
- Theme switcher notlari: `theme-switcher.md`
- Kurulum sayfasi referansi: `app/docs/installation/page.tsx`
---
Bu dokuman "proje ici operasyonel guide" amaciyla yazildi.
Paketin public-facing README'sini sade tutup, bu dosyayi teknik detay merkezi olarak kullanman tavsiye edilir.

Before

Width:  |  Height:  |  Size: 1.4 MiB

After

Width:  |  Height:  |  Size: 1.4 MiB

Before

Width:  |  Height:  |  Size: 1.4 MiB

After

Width:  |  Height:  |  Size: 1.4 MiB

Before

Width:  |  Height:  |  Size: 1.6 MiB

After

Width:  |  Height:  |  Size: 1.6 MiB

Before

Width:  |  Height:  |  Size: 914 KiB

After

Width:  |  Height:  |  Size: 914 KiB

Before

Width:  |  Height:  |  Size: 1.3 MiB

After

Width:  |  Height:  |  Size: 1.3 MiB

Before

Width:  |  Height:  |  Size: 1.6 MiB

After

Width:  |  Height:  |  Size: 1.6 MiB

Before

Width:  |  Height:  |  Size: 1.2 MiB

After

Width:  |  Height:  |  Size: 1.2 MiB

Before

Width:  |  Height:  |  Size: 1.2 MiB

After

Width:  |  Height:  |  Size: 1.2 MiB

Before

Width:  |  Height:  |  Size: 1.7 MiB

After

Width:  |  Height:  |  Size: 1.7 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 908 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 MiB

+135 -88
View File
@@ -1,8 +1,11 @@
-- 0001: Initial Cognis baseline schema
-- This file is intentionally idempotent enough to be retried after a failed SQL Editor run.
-- Enable necessary extensions -- Enable necessary extensions
create extension if not exists "uuid-ossp"; create extension if not exists "uuid-ossp";
-- 1. Create journals table -- 1. Create journals table
create table public.journals ( create table if not exists public.journals (
id uuid default uuid_generate_v4() primary key, id uuid default uuid_generate_v4() primary key,
user_id uuid references auth.users(id) on delete cascade not null, user_id uuid references auth.users(id) on delete cascade not null,
date timestamp with time zone default timezone('utc'::text, now()) not null, date timestamp with time zone default timezone('utc'::text, now()) not null,
@@ -19,7 +22,7 @@ create table public.journals (
); );
-- 2. Create tasks table -- 2. Create tasks table
create table public.tasks ( create table if not exists public.tasks (
id uuid default uuid_generate_v4() primary key, id uuid default uuid_generate_v4() primary key,
user_id uuid references auth.users(id) on delete cascade not null, user_id uuid references auth.users(id) on delete cascade not null,
date timestamp with time zone default timezone('utc'::text, now()) not null, date timestamp with time zone default timezone('utc'::text, now()) not null,
@@ -33,7 +36,7 @@ create table public.tasks (
); );
-- 3. Create chat_sessions table -- 3. Create chat_sessions table
create table public.chat_sessions ( create table if not exists public.chat_sessions (
id uuid default uuid_generate_v4() primary key, id uuid default uuid_generate_v4() primary key,
user_id uuid references auth.users(id) on delete cascade not null, user_id uuid references auth.users(id) on delete cascade not null,
title text not null, title text not null,
@@ -42,7 +45,7 @@ create table public.chat_sessions (
); );
-- 4. Create chat_messages table -- 4. Create chat_messages table
create table public.chat_messages ( create table if not exists public.chat_messages (
id uuid default uuid_generate_v4() primary key, id uuid default uuid_generate_v4() primary key,
session_id uuid references public.chat_sessions(id) on delete cascade not null, session_id uuid references public.chat_sessions(id) on delete cascade not null,
role text not null, role text not null,
@@ -51,80 +54,8 @@ create table public.chat_messages (
created_at timestamp with time zone default timezone('utc'::text, now()) not null created_at timestamp with time zone default timezone('utc'::text, now()) not null
); );
-- RLS (Row Level Security) Policies
alter table public.journals enable row level security;
alter table public.tasks enable row level security;
alter table public.chat_sessions enable row level security;
alter table public.chat_messages enable row level security;
-- Journals Policies
create policy "Users can view their own journals." on public.journals
for select using (auth.uid() = user_id);
create policy "Users can insert their own journals." on public.journals
for insert with check (auth.uid() = user_id);
create policy "Users can update their own journals." on public.journals
for update using (auth.uid() = user_id);
create policy "Users can delete their own journals." on public.journals
for delete using (auth.uid() = user_id);
-- Tasks Policies
create policy "Users can view their own tasks." on public.tasks
for select using (auth.uid() = user_id);
create policy "Users can insert their own tasks." on public.tasks
for insert with check (auth.uid() = user_id);
create policy "Users can update their own tasks." on public.tasks
for update using (auth.uid() = user_id);
create policy "Users can delete their own tasks." on public.tasks
for delete using (auth.uid() = user_id);
-- Chat Sessions Policies
create policy "Users can view their own chat sessions." on public.chat_sessions
for select using (auth.uid() = user_id);
create policy "Users can insert their own chat sessions." on public.chat_sessions
for insert with check (auth.uid() = user_id);
create policy "Users can update their own chat sessions." on public.chat_sessions
for update using (auth.uid() = user_id);
create policy "Users can delete their own chat sessions." on public.chat_sessions
for delete using (auth.uid() = user_id);
-- Chat Messages Policies
-- Assuming users can only access messages in their own sessions
create policy "Users can view their own chat messages." on public.chat_messages
for select using (
exists (
select 1 from public.chat_sessions
where chat_sessions.id = chat_messages.session_id
and chat_sessions.user_id = auth.uid()
)
);
create policy "Users can insert their own chat messages." on public.chat_messages
for insert with check (
exists (
select 1 from public.chat_sessions
where chat_sessions.id = session_id
and chat_sessions.user_id = auth.uid()
)
);
create policy "Users can update their own chat messages." on public.chat_messages
for update using (
exists (
select 1 from public.chat_sessions
where chat_sessions.id = session_id
and chat_sessions.user_id = auth.uid()
)
);
create policy "Users can delete their own chat messages." on public.chat_messages
for delete using (
exists (
select 1 from public.chat_sessions
where chat_sessions.id = session_id
and chat_sessions.user_id = auth.uid()
)
);
-- 5. Create profiles table -- 5. Create profiles table
create table public.profiles ( create table if not exists public.profiles (
id uuid references auth.users(id) on delete cascade primary key, id uuid references auth.users(id) on delete cascade primary key,
first_name text, first_name text,
last_name text, last_name text,
@@ -132,29 +63,133 @@ create table public.profiles (
updated_at timestamp with time zone default timezone('utc'::text, now()) not null updated_at timestamp with time zone default timezone('utc'::text, now()) not null
); );
-- RLS (Row Level Security)
alter table public.journals enable row level security;
alter table public.tasks enable row level security;
alter table public.chat_sessions enable row level security;
alter table public.chat_messages enable row level security;
alter table public.profiles enable row level security; alter table public.profiles enable row level security;
-- Journals policies
drop policy if exists "Users can view their own journals." on public.journals;
create policy "Users can view their own journals." on public.journals
for select using (auth.uid() = user_id);
drop policy if exists "Users can insert their own journals." on public.journals;
create policy "Users can insert their own journals." on public.journals
for insert with check (auth.uid() = user_id);
drop policy if exists "Users can update their own journals." on public.journals;
create policy "Users can update their own journals." on public.journals
for update using (auth.uid() = user_id);
drop policy if exists "Users can delete their own journals." on public.journals;
create policy "Users can delete their own journals." on public.journals
for delete using (auth.uid() = user_id);
-- Tasks policies
drop policy if exists "Users can view their own tasks." on public.tasks;
create policy "Users can view their own tasks." on public.tasks
for select using (auth.uid() = user_id);
drop policy if exists "Users can insert their own tasks." on public.tasks;
create policy "Users can insert their own tasks." on public.tasks
for insert with check (auth.uid() = user_id);
drop policy if exists "Users can update their own tasks." on public.tasks;
create policy "Users can update their own tasks." on public.tasks
for update using (auth.uid() = user_id);
drop policy if exists "Users can delete their own tasks." on public.tasks;
create policy "Users can delete their own tasks." on public.tasks
for delete using (auth.uid() = user_id);
-- Chat sessions policies
drop policy if exists "Users can view their own chat sessions." on public.chat_sessions;
create policy "Users can view their own chat sessions." on public.chat_sessions
for select using (auth.uid() = user_id);
drop policy if exists "Users can insert their own chat sessions." on public.chat_sessions;
create policy "Users can insert their own chat sessions." on public.chat_sessions
for insert with check (auth.uid() = user_id);
drop policy if exists "Users can update their own chat sessions." on public.chat_sessions;
create policy "Users can update their own chat sessions." on public.chat_sessions
for update using (auth.uid() = user_id);
drop policy if exists "Users can delete their own chat sessions." on public.chat_sessions;
create policy "Users can delete their own chat sessions." on public.chat_sessions
for delete using (auth.uid() = user_id);
-- Chat messages policies
drop policy if exists "Users can view their own chat messages." on public.chat_messages;
create policy "Users can view their own chat messages." on public.chat_messages
for select using (
exists (
select 1 from public.chat_sessions
where chat_sessions.id = chat_messages.session_id
and chat_sessions.user_id = auth.uid()
)
);
drop policy if exists "Users can insert their own chat messages." on public.chat_messages;
create policy "Users can insert their own chat messages." on public.chat_messages
for insert with check (
exists (
select 1 from public.chat_sessions
where chat_sessions.id = session_id
and chat_sessions.user_id = auth.uid()
)
);
drop policy if exists "Users can update their own chat messages." on public.chat_messages;
create policy "Users can update their own chat messages." on public.chat_messages
for update using (
exists (
select 1 from public.chat_sessions
where chat_sessions.id = session_id
and chat_sessions.user_id = auth.uid()
)
);
drop policy if exists "Users can delete their own chat messages." on public.chat_messages;
create policy "Users can delete their own chat messages." on public.chat_messages
for delete using (
exists (
select 1 from public.chat_sessions
where chat_sessions.id = session_id
and chat_sessions.user_id = auth.uid()
)
);
-- Profiles policies
drop policy if exists "Users can view their own profile." on public.profiles;
create policy "Users can view their own profile." on public.profiles create policy "Users can view their own profile." on public.profiles
for select using (auth.uid() = id); for select using (auth.uid() = id);
drop policy if exists "Users can insert their own profile." on public.profiles;
create policy "Users can insert their own profile." on public.profiles create policy "Users can insert their own profile." on public.profiles
for insert with check (auth.uid() = id); for insert with check (auth.uid() = id);
drop policy if exists "Users can update their own profile." on public.profiles;
create policy "Users can update their own profile." on public.profiles create policy "Users can update their own profile." on public.profiles
for update using (auth.uid() = id); for update using (auth.uid() = id);
-- Function to handle new user signup -- Function to handle new user signup
create or replace function public.handle_new_user() create or replace function public.handle_new_user()
returns trigger as $$$ returns trigger as $$
begin begin
insert into public.profiles (id, first_name, last_name, avatar_url) insert into public.profiles (id, first_name, last_name, avatar_url)
values (new.id, '', '', ''); values (new.id, '', '', '')
on conflict (id) do nothing;
return new; return new;
end; end;
$$$ language plpgsql security definer; $$ language plpgsql security definer;
-- Drop trigger if exists to avoid errors on multiple runs
drop trigger if exists on_auth_user_created on auth.users;
-- Trigger to automatically create profile on signup -- Trigger to automatically create profile on signup
drop trigger if exists on_auth_user_created on auth.users;
create trigger on_auth_user_created create trigger on_auth_user_created
after insert on auth.users after insert on auth.users
for each row execute procedure public.handle_new_user(); for each row execute procedure public.handle_new_user();
@@ -164,19 +199,31 @@ insert into storage.buckets (id, name, public)
values ('avatars', 'avatars', true) values ('avatars', 'avatars', true)
on conflict (id) do nothing; on conflict (id) do nothing;
drop policy if exists "Avatar images are publicly accessible." on storage.objects;
create policy "Avatar images are publicly accessible." create policy "Avatar images are publicly accessible."
on storage.objects for select on storage.objects for select
using ( bucket_id = 'avatars' ); using (bucket_id = 'avatars');
drop policy if exists "Users can upload an avatar." on storage.objects;
create policy "Users can upload an avatar." create policy "Users can upload an avatar."
on storage.objects for insert on storage.objects for insert
with check ( bucket_id = 'avatars' AND auth.uid()::text = (storage.foldername(name))[1] ); with check (
bucket_id = 'avatars'
and auth.uid()::text = (storage.foldername(name))[1]
);
drop policy if exists "Users can update their own avatar." on storage.objects;
create policy "Users can update their own avatar." create policy "Users can update their own avatar."
on storage.objects for update on storage.objects for update
using ( bucket_id = 'avatars' AND auth.uid()::text = (storage.foldername(name))[1] ); using (
bucket_id = 'avatars'
and auth.uid()::text = (storage.foldername(name))[1]
);
drop policy if exists "Users can delete their own avatar." on storage.objects;
create policy "Users can delete their own avatar." create policy "Users can delete their own avatar."
on storage.objects for delete on storage.objects for delete
using ( bucket_id = 'avatars' AND auth.uid()::text = (storage.foldername(name))[1] ); using (
bucket_id = 'avatars'
and auth.uid()::text = (storage.foldername(name))[1]
);