Initial commit: Lookbook personal collection app

Pinterest-like app for saving images, videos, quotes, and embeds.

Features:
- Go backend with PostgreSQL, SSR templates
- Console-based admin auth (login/logout via browser console)
- Item types: images, videos (ffmpeg transcoding), quotes, embeds
- Media stored as BLOBs in PostgreSQL
- OpenGraph metadata extraction for links
- Embed detection for YouTube, Vimeo, Twitter/X
- Masonry grid layout, item detail pages
- Tag system with filtering
- Refresh metadata endpoint with change warnings
- Replace media endpoint for updating item images/videos
This commit is contained in:
soup 2026-01-17 01:09:23 -05:00
commit cdcc5b5293
Signed by: soup
SSH key fingerprint: SHA256:GYxje8eQkJ6HZKzVWDdyOUF1TyDiprruGhE0Ym8qYDY
45 changed files with 4634 additions and 0 deletions

View file

@ -0,0 +1,73 @@
package session
import (
"context"
"database/sql"
"time"
)
type Row struct {
ID int64
SessionID string
CreatedAt time.Time
ExpiresAt time.Time
}
// QCreate creates a new session.
func QCreate(ctx context.Context, db *sql.DB, sessionID string, expiresAt time.Time) (Row, error) {
query := `
INSERT INTO session (session_id, expires_at)
VALUES ($1, $2)
RETURNING id, session_id, created_at, expires_at
`
var row Row
err := db.QueryRowContext(ctx, query, sessionID, expiresAt).Scan(
&row.ID,
&row.SessionID,
&row.CreatedAt,
&row.ExpiresAt,
)
return row, err
}
// QFindBySessionID finds a session by its session ID.
// Returns (nil, nil) if the session does not exist.
func QFindBySessionID(ctx context.Context, db *sql.DB, sessionID string) (*Row, error) {
query := `
SELECT id, session_id, created_at, expires_at
FROM session
WHERE session_id = $1
LIMIT 1
`
var row Row
err := db.QueryRowContext(ctx, query, sessionID).Scan(
&row.ID,
&row.SessionID,
&row.CreatedAt,
&row.ExpiresAt,
)
if err == sql.ErrNoRows {
return nil, nil
}
if err != nil {
return nil, err
}
return &row, nil
}
// QDelete deletes a session by its session ID.
func QDelete(ctx context.Context, db *sql.DB, sessionID string) error {
query := `DELETE FROM session WHERE session_id = $1`
_, err := db.ExecContext(ctx, query, sessionID)
return err
}
// QDeleteExpired deletes all expired sessions.
func QDeleteExpired(ctx context.Context, db *sql.DB) error {
query := `DELETE FROM session WHERE expires_at < NOW()`
_, err := db.ExecContext(ctx, query)
return err
}