Edit of links and database versioning

This commit is contained in:
Olaf
2026-08-24 19:39:21 +02:00
parent ff249ec911
commit 28a01175f7
12 changed files with 239 additions and 8 deletions
+25 -1
View File
@@ -1,7 +1,7 @@
from fastapi import APIRouter, Header, HTTPException, status
from pydantic import BaseModel
from backend.app.services.link_service import create_link, list_public_links
from backend.app.services.link_service import create_link, list_public_links, update_link
from backend.app.services.plugin_manager import plugin_manager
from backend.app.services.token_service import validate_token
@@ -15,6 +15,12 @@ class LinkCreate(BaseModel):
timestamp: str | None = None
class LinkUpdate(BaseModel):
title: str
url: str
comment: str = ''
@router.post('/links', status_code=status.HTTP_201_CREATED)
def create_link_endpoint(payload: LinkCreate, authorization: str | None = Header(default=None)):
if not authorization or not authorization.startswith('Bearer '):
@@ -29,6 +35,24 @@ def create_link_endpoint(payload: LinkCreate, authorization: str | None = Header
return record
@router.put('/links/{link_id}')
def update_link_endpoint(
link_id: str,
payload: LinkUpdate,
authorization: str | None = Header(default=None),
):
if not authorization or not authorization.startswith('Bearer '):
raise HTTPException(status_code=401, detail='Missing or invalid Authorization header')
info = validate_token(authorization.replace('Bearer ', '', 1))
if info is None:
raise HTTPException(status_code=401, detail='Token expired or invalid')
record = update_link(link_id, info['user_id'], payload.title, payload.url, payload.comment)
if record is None:
raise HTTPException(status_code=404, detail='Link not found or not owned by user')
return record
@router.get('/links')
def list_links():
return list_public_links()
+15 -2
View File
@@ -1,8 +1,11 @@
from fastapi import APIRouter
from fastapi import APIRouter, Depends
from fastapi.security import HTTPAuthorizationCredentials, HTTPBearer
from backend.app.services.link_service import list_public_links, list_public_users
from backend.app.services.token_service import validate_token
router = APIRouter()
optional_bearer = HTTPBearer(auto_error=False)
@router.get('/users')
@@ -12,7 +15,15 @@ def public_users():
@router.get('/feed')
@router.get('/feed/{username}')
def public_feed(username: str | None = None):
def public_feed(
username: str | None = None,
credentials: HTTPAuthorizationCredentials | None = Depends(optional_bearer),
):
current_user_id = None
if credentials:
token_data = validate_token(credentials.credentials)
if token_data:
current_user_id = token_data['user_id']
items = list_public_links(username)
return [
{
@@ -25,6 +36,8 @@ def public_feed(username: str | None = None):
'avatar_url': item['avatar_url'],
'bio': item['bio'],
},
'is_owner': item['user_id'] == current_user_id,
'can_edit': item['user_id'] == current_user_id,
'created_at': item['created_at'],
}
for item in items
+19 -3
View File
@@ -13,7 +13,8 @@ AVATARS_DIR.mkdir(parents=True, exist_ok=True)
def hash_password(password: str) -> str:
return sha256(password.encode('utf-8')).hexdigest()
SCHEMA = '''
MIGRATIONS = [
(1, '''
CREATE TABLE IF NOT EXISTS users (
id TEXT PRIMARY KEY,
username TEXT NOT NULL UNIQUE,
@@ -70,7 +71,8 @@ CREATE TABLE IF NOT EXISTS user_plugin_config (
UNIQUE(user_id, plugin_name),
FOREIGN KEY(user_id) REFERENCES users(id)
);
'''
'''),
]
def get_connection() -> sqlite3.Connection:
@@ -80,9 +82,23 @@ def get_connection() -> sqlite3.Connection:
return conn
def get_schema_version(conn: sqlite3.Connection) -> int:
return conn.execute('PRAGMA user_version').fetchone()[0]
def apply_migrations(conn: sqlite3.Connection) -> None:
current_version = get_schema_version(conn)
for version, sql in MIGRATIONS:
if version <= current_version:
continue
conn.executescript(sql)
conn.execute(f'PRAGMA user_version = {version}')
conn.commit()
def init_db() -> None:
with get_connection() as conn:
conn.executescript(SCHEMA)
apply_migrations(conn)
alice_hash = hash_password('secret123')
bob_hash = hash_password('secret123')
conn.execute(
+18
View File
@@ -57,6 +57,24 @@ def list_public_links(username: str | None = None):
return [dict(row) for row in rows]
def update_link(link_id: str, user_id: str, title: str, url: str, comment: str):
cleaned_url = clean_url(url)
with get_connection() as conn:
cursor = conn.execute(
'''
UPDATE links
SET title = ?, url = ?, comment = ?, updated_at = CURRENT_TIMESTAMP
WHERE id = ? AND user_id = ?
''',
(title, cleaned_url, comment, link_id, user_id),
)
if cursor.rowcount == 0:
return None
conn.commit()
row = conn.execute('SELECT * FROM links WHERE id = ?', (link_id,)).fetchone()
return dict(row)
def list_public_users():
with get_connection() as conn:
rows = conn.execute(