CREATE TABLE users (
    id          INTEGER PRIMARY KEY AUTOINCREMENT,
    username    VARCHAR(64)  NOT NULL UNIQUE,
    email       VARCHAR(255) NOT NULL UNIQUE,
    password    CHAR(64)     NOT NULL,
    is_active   BOOLEAN      NOT NULL DEFAULT TRUE,
    role        VARCHAR(32)  NOT NULL DEFAULT 'user',
    created_at  TIMESTAMP    NOT NULL DEFAULT CURRENT_TIMESTAMP,
    updated_at  TIMESTAMP    NOT NULL DEFAULT CURRENT_TIMESTAMP
);

CREATE TABLE posts (
    id          INTEGER PRIMARY KEY AUTOINCREMENT,
    author_id   INTEGER      NOT NULL REFERENCES users(id) ON DELETE CASCADE,
    title       VARCHAR(200) NOT NULL,
    slug        VARCHAR(200) NOT NULL UNIQUE,
    body        TEXT         NOT NULL,
    status      VARCHAR(16)  NOT NULL DEFAULT 'draft'
                             CHECK (status IN ('draft', 'published', 'archived')),
    view_count  INTEGER      NOT NULL DEFAULT 0,
    published_at TIMESTAMP,
    created_at  TIMESTAMP    NOT NULL DEFAULT CURRENT_TIMESTAMP
);

SELECT
    u.username,
    u.email,
    p.title,
    p.status,
    p.view_count
FROM users u
JOIN posts p ON p.author_id = u.id
WHERE u.is_active = TRUE
  AND p.status != 'archived'
ORDER BY p.created_at DESC
LIMIT 20;

WITH cte AS (
    SELECT author_id, COUNT(*) AS cnt
    FROM posts
    GROUP BY author_id
)
SELECT u.username, cte.cnt
FROM users u
JOIN cte ON cte.author_id = u.id;

UPDATE posts
SET status = 'archived',
    updated_at = CURRENT_TIMESTAMP
WHERE published_at < datetime('now', '-1 year')
  AND status = 'published';

SELECT
    NULL AS maybe_value,
    COALESCE(u.email, 'no-email') AS safe_email,
    CASE
        WHEN p.view_count > 1000 THEN 'popular'
        WHEN p.view_count > 100  THEN 'moderate'
        ELSE 'quiet'
    END AS popularity
FROM users u
LEFT JOIN posts p ON p.author_id = u.id;
