A little blog server, written in Rust
  • Rust 64.8%
  • CSS 27.8%
  • Mermaid 4.2%
  • Dockerfile 3.2%
Find a file
2026-03-27 18:23:14 +01:00
.continue/rules stupid AI stuff... undo everything to here to get back to normal. 2026-03-11 15:59:50 +01:00
entity more specific column types 2026-03-17 11:26:10 +01:00
migration WIP: adding tables 2026-03-12 15:53:21 +01:00
src move back to /data 2026-03-27 18:23:14 +01:00
static most important shit ever! 2026-03-18 08:41:19 +01:00
templates use layout and src formatting 2026-03-18 20:31:16 +01:00
.gitignore ignore ai stuff/prmpts/whatever 2026-03-14 21:29:57 +01:00
Cargo.lock cargo update 2026-03-26 16:57:58 +01:00
Cargo.toml changes required to shutdown correctly in a container 2026-03-23 13:07:30 +01:00
Containerfile move back to /data 2026-03-27 18:23:14 +01:00
README.md remove a bunch of Ai generated garbage... 2026-03-13 19:14:11 +00:00

Poetry Blog - Books Built from Posts

A Rust-based web application built with SeaORM, Poem, and SQLite that allows users to create authors, write blog posts, and compile those posts into books. Think of it as a self-publishing platform where your writings become books.


📚 Project Overview

  1. Authors write individual blog posts
  2. Posts are published on a blog
  3. Books are created by selecting and ordering specific posts as their chapters/contents

Key Features

  • Create authors with profiles and avatars
  • Write and publish individual blog posts
  • Compile posts into books (each book can have multiple posts as "contents")
  • Maintain display order for posts within books
  • Full CRUD operations for all entities
  • Relational database with proper foreign key constraints
  • Image upload support (stored as Blobs)

Database Schema


erDiagram
    author {
        bigint id PK
        text first_name
        text last_name
        text middle_name
        text bio
        blob avatar
        text email
        custom display_name
        text created_at
        text updated_at
        bigint rback_role_id FK
    }
    book_attribution {
        bigint book_id PK,FK
        bigint author_id PK,FK
        text attribution
    }
    book_contents {
        bigint book_id PK,FK
        bigint post_id PK,FK
        bigint display_order
    }
    books {
        bigint id PK
        text title
        text author_id FK
        text publish_date
        text created_at
        text blurb
        blob image
        text status
    }
    posts {
        bigint id PK
        bigint author_id FK
        text post_status
        text title
        text content
        text created_at
        bigint updated_at
        blob image
    }
    rbac_roles {
        bigint id PK
        text name
        text description
    }
    author }o--|| rbac_roles : "rback_role_id"
    author }o--o{ books : "[book_attribution]"
    book_attribution }o--|| author : "author_id"
    book_attribution }o--|| books : "book_id"
    book_contents }o--|| books : "book_id"
    book_contents }o--|| posts : "post_id"
    books }o--|| author : "author_id"
    books }o--o{ posts : "[book_contents]"
    posts }o--|| author : "author_id"

The application uses SQLite with four main tables:

Table Description Relationships
author Stores author information Has many books, has many posts
books Individual books with metadata Belongs to author, has many contents
posts Individual blog posts Belongs to author, in many books
book_contents Join table linking books to posts Foreign keys to both books & posts
book_attribution Join table for author/editor roles Foreign keys to author & books
rbac_roles stores app auth roles for data access. simple role lookup table

🛠️ Tech Stack

  • Language: Rust
  • Web Framework: Poem (async HTTP framework)
  • ORM: SeaORM (asynchronous Rust ORM)
  • Database: SQLite (embedded, zero-configuration)
  • Migrations: SeaORM Migrations crate
  • Async Runtime: Tokio (via Poem)

📦 [Proposed] Project Structure

poetry-blog/
├── Cargo.toml
├── Cargo.lock
├── .env (environment configuration)
├── .env.example
├── README.md
├── README-books-posts.md
├── entity/                 # SeaORM entities
│   ├── src/
│   │   ├── mod.rs
│   │   ├── author.rs       # Author entity
│   │   ├── books.rs        # Book entity
│   │   ├── posts.rs        # Post entity
│   │   └── book_contents.rs # Join table entity
│   ├── entities/           # Generated entity structs
│   └── migrations/         # Entity migration scripts
├── migration/              # SeaORM migrations
│   ├── src/
│   │   ├── lib.rs          # Migration library
│   │   ├── main.rs         # Migration executable
│   │   ├── m20220101_000001_create_table.rs  # Original migration
│   │   └── m20240101_000001_create_tables.rs # NEW: Corrected schema
│   └── migrations/         # Migration snapshots
├── src/                    # Main application
│   ├── main.rs             # Application entry point
│   ├── routes/             # Route definitions
│   │   ├── mod.rs
│   │   ├── posts.rs
│   │   ├── books.rs
│   │   └── pages.rs
│   ├── handlers/           # Route handlers
│   │   ├── mod.rs
│   │   ├── posts.rs
│   │   ├── books.rs
│   │   └── pages.rs
│   ├── db/                 # Database utilities
│   │   └── mod.rs
│   ├── models/             # Data models (DTOs)
│   │   ├── author.rs
│   │   ├── book.rs
│   │   ├── post.rs
│   │   └── book_content.rs
│   └── config/             # Configuration
│       └── mod.rs
└── tests/                  # Integration tests
    └── integration_test.rs

🚀 Getting Started

Prerequisites

  • Rust 1.70+ installed
  • SQLite dev stuff (sqlite-dev)

Access the application: Open your browser and navigate to: http://localhost:3000


🗄️ Database Setup

First 1. Migrate to create tables

The SeaORM migration system automatically creates the database schema when you run the application for the first time. The migration will:

  1. Create the author table
  2. Create the books table with foreign key to author
  3. Create the posts table with foreign key to author
  4. Create the book_contents join table ... TODO!

Manual Migration (if needed)

TODO!


🌐 API Endpoints (Current Implementation)

Books

Method Endpoint Description
POST /books Create a new book
GET /books List all books
GET /books/:id Get a specific book
POST /books/:id/image Upload book image

Posts

Method Endpoint Description
GET / List all posts (home page)
GET /:id Get a specific post
POST /posts Create a new post

Authors

Method Endpoint Description
GET /authors List all authors
POST /authors Create a new author

Development Tips

Adding New Routes

  1. Define your route in src/routes/mod.rs
  2. Create the handler in src/handlers/[entity].rs
  3. Create data models in src/models/[entity].rs

Database Operations / Useful commands/code

Use SeaORM's entity methods for database operations:

// Example: Create a new author
use entity::author;

let author = author::Entity::insert(new_author)
    .exec(db)
    .await?;

Working with Relationships

// Load posts for a book
use entity::book_contents;

let contents = book_contents::Entity::find()
    .belongs_to(books::Entity)
    .and_related_to(books::Entity::find_by_id(book_id))
    .all(db)
    .await?;

📝 Notes for Developers

Important Schema Decisions

  1. Author ID Type Consistency: Both books.author_id and posts.author_id use i64 to match the author.id type. This ensures foreign key consistency.

  2. BookContents Join Table: The book_contents table:

    • Uses a composite primary key (book_id, post_id)
    • Tracks display_order to maintain chapter/page sequencing
    • Uses NoAction for foreign key constraints (no cascading deletes) ... should change this?
  3. Image Storage: All images are stored as Blob fields in the database. For production, consider moving to file storage (S3, local disk, etc.).

  4. Cascade vs NoAction:

    • Cascade on author relations: Deleting an author deletes their books/posts
    • NoAction on book_contents: Prevents deleting referenced books/posts

🔮 Future Enhancements

  • Add pagination to list endpoints
  • Implement search/filter capabilities
  • Add input validation with serde_json::value::Value
  • Implement image upload to file system instead of DB Blobs
  • Add API documentation with Swagger/OpenAPI
  • Implement user authentication/authorization
  • Add email notifications for new book publications
  • Create an admin dashboard

📜 License

This project is licensed under the GPL 2.0 License - see the LICENSE file for details.