Skip to content

linarawwas/Fahrenheit-Backend

Repository files navigation

Fahrenheit Backend

This repository contains the current Laravel backend for the Fahrenheit reading application. In its present state, the project is a Laravel 10 API that combines authentication, book storage, Project Gutenberg scraping, reading progress tracking, streaks, notes, a personal Secret Attic, and a purchasable Secret Vault system backed by Laravel Sanctum authentication.1 2 3

The codebase is not a generic Laravel starter anymore, even though the existing README was still the default framework boilerplate. The implemented backend is clearly oriented around a gamified reading experience in which users read books, earn rank through reading activity, preserve streaks, collect books, and spend accumulated reading rank on premium or hidden content.2 4 5 6

Current backend scope

The API surface is organized around several user-facing systems rather than a single CRUD domain. Authentication endpoints manage account access, book endpoints manage the shared book catalog, reading-progress endpoints track user activity, note endpoints support annotations, and the attic/vault endpoints add collection and economy mechanics on top of the base reading flow.2

Domain Purpose Main sources
Authentication User registration, login, logout, and Sanctum token access 2 4
Users and profile Profile retrieval, profile updates, username/profile picture lookup, deletion, and reading-rank retrieval 2 5
Books Store imported books, retrieve catalog, fetch random books, and increment ratings 2 6
Scraping and reading content Scrape Gutenberg book metadata or page contents for in-app reading 2 7
Reading progress and streaks Start reading, finish reading, mark daily reading, and retrieve streak/progress state 2 8 9
Notes Create, update, list, filter, and delete user notes attached to books 2 10
Secret Attic Personal saved-book area for unread or selected books 2 11
Secret Books and Secret Vault Purchasable premium books using reading rank as currency 2 12

Server architecture

The repository is a standard Laravel application using PHP 8.1+, Laravel 10.8, Sanctum, and a minimal Vite asset pipeline.1 13 The backend also includes Goutte and Symfony DomCrawler, which are central to the scraping and page-extraction behavior used against Project Gutenberg content.1 7

Layer Current implementation
Framework Laravel 10
Language PHP 8.1+
Auth Laravel Sanctum personal access tokens
Scraping Goutte + Symfony DomCrawler
Database support Laravel DB layer with MySQL defaults in .env.example
Frontend tooling in repo Vite, Axios bootstrap

Authentication model

Authentication is implemented through Laravel Sanctum. The route file exposes login, register, and logout endpoints through the API auth controller, while most other endpoints are protected with the auth:sanctum middleware.2 Login validates a submitted username and password, and on success returns the authenticated user together with a newly created API token under an authorization object.4

Registration currently validates username, password, email, and an optional uploaded profile_picture image.4 During registration, the backend also creates an initial ReadingStreak record for the new user with a starting streak of 1, which shows that streak mechanics are part of the onboarding flow rather than an optional add-on.4

Auth endpoint Method Access Current behavior
/api/login POST Public Authenticate by username/password and return token
/api/register POST Public Create user and initialize reading streak
/api/logout POST Public in route file, but expects authenticated user Delete current user's tokens
/api/user GET Authenticated Return authenticated user
/api/tokens/create POST Token-oriented route Create token from current user context

One practical implementation note is that /api/logout is placed inside the auth-controller group without explicit auth:sanctum middleware at the route level, even though the controller expects an authenticated user to exist.2 That is worth knowing when integrating clients against the current backend.

API route summary

The route file documents a fairly broad application backend. Almost every non-auth action requires Sanctum authentication, reflecting the product's user-account-centric design.2

Base path Endpoint Access Purpose
/api POST /login Public Login by username
/api POST /register Public Register account
/api POST /logout Controller expects auth Logout current user
/api GET /users Authenticated List users
/api DELETE /user Authenticated Permanently delete selected users
/api DELETE /user/hibernate Authenticated Intended soft-delete route
/api GET /user/username Authenticated Get current username
/api GET /user/profile-picture Authenticated Get profile picture path
/api PUT /user Authenticated Update current user
/api GET /user/readingrank Authenticated Get reading rank
/api GET /profile Authenticated Get current user with reading streak
/api POST /books Authenticated Bulk store books
/api GET /books Authenticated List all books
/api GET /books/random Authenticated Fetch one random book
/api GET /books/randomCollection Authenticated Fetch six random books
/api PUT /books/increment-rating Authenticated Increase book rating
/api GET /scrape-books Authenticated Scraping/import-related route
/api GET /secret-attic/scrape-page-contents Authenticated Scrape readable page content from a saved attic book
/api POST /books/browse Authenticated Scrape readable page content for a specific book
/api POST /readingprogress/start-reading Authenticated Start reading a book
/api PUT /readingprogress/finish-reading Authenticated Finish reading a book
/api GET /reading-progress Authenticated Retrieve current user's reading progress
/api POST /read-today Authenticated Update daily reading streak
/api GET /reading-streak Authenticated Retrieve current and longest streak
/api POST /notes Authenticated Add note
/api PUT /notes/{note} Authenticated Update note
/api GET /notes Authenticated View notes
/api GET /notes/book/{book} Authenticated View notes by book
/api DELETE /notes/{id} Authenticated Delete note
/api POST /secret-attic/add-book Authenticated Add book to Secret Attic
/api GET /secret-attic/books Authenticated View Secret Attic books
/api GET /secret-attic/book-urls Authenticated View Secret Attic URLs
/api GET /secret-attic/count Authenticated Count Secret Attic books
/api PUT /secret-attic/burn Authenticated Mark Secret Attic book as received
/api POST /secret-books Authenticated Create secret book
/api POST /secret-books/multiple Authenticated Bulk create secret books
/api PUT /secret-books/price Authenticated Update secret book price
/api POST /secret-books/purchase-book Authenticated Purchase secret book with rank
/api GET /secret-books Authenticated List secret books
/api GET /user/secret-vault/books Authenticated Get purchased vault books
/api DELETE /secret-books Authenticated Delete all secret books

Core gameplay and reading loop

The most distinctive part of this backend is that it treats reading as a progression system. When a user starts reading a book, the backend records a started_reading_at timestamp in the reading_progress pivot table and increases the user's reading_rank by 1.8 When the user finishes a book, the backend writes finished_reading_at and increases reading_rank by 2.8 Notes also contribute to progression, because adding a note grants additional reading rank.10

Daily engagement is handled separately through readToday(), which updates or creates a ReadingStreak, checks whether the user already read on the current date, increments the streak if yesterday was also a reading day, or resets the streak if continuity was lost.8 The resulting streak is written both to the separate streak table and back onto the user record via current_reading_streak and longest_reading_streak fields.5 8

Reading action Current reward or effect
Start reading Creates/updates reading-progress row and adds +1 reading rank
Finish reading Updates reading-progress row and adds +2 reading rank
Read today Extends or resets daily streak depending on last reading date
Add note Increases reading rank further
Reach rank threshold Enables secret-book purchasing if rank is high enough

User, profile, and progress data

The User model makes it clear that the application stores more than basic auth data. In addition to username, password, and email, the model persists reading_rank, current_reading_streak, and longest_reading_streak as first-class user fields.5 It also defines relationships to notes, reading streaks, reading progress, regular books, the secret attic, and the secret vault.5

User-related capability Current implementation
Profile retrieval /api/profile returns authenticated user with readingStreak relation
Username lookup /api/user/username returns current username
Profile picture lookup /api/user/profile-picture returns stored file name/path
Profile update /api/user updates username, password, email, and optional profile picture
Reading rank lookup /api/user/readingrank returns current rank
Account deletion Permanent delete via /api/user; intended soft delete route also exists

Profile picture uploads are handled by moving the uploaded file into public/profile_picture during both registration and update flows.4 5 The model also uses soft deletes, which fits the existence of the hibernation-style user route, even though the route and controller method names do not perfectly match in the current code.5

Book catalog and Gutenberg integration

The standard books domain stores Project Gutenberg book metadata such as pg_id, title, author, language, url, and ratings.6 Books can be inserted in bulk through the store() method, retrieved as a full catalog, or sampled randomly for recommendation-like behavior.6

The backend also includes a scraping controller built with Goutte and DomCrawler. In its current active form, BrowseBook() loads a specific book URL from the database and extracts the HTML contents after Gutenberg's boilerplate header, while scrapePageContents() performs a similar extraction using a random book from the authenticated user's Secret Attic.7 This indicates the repository is designed not only to store book metadata but also to serve readable book content inside the app experience.7

Secret Attic and Secret Vault systems

The Secret Attic is a personal saved-book space tied to the authenticated user.11 If a user does not yet have one, the backend creates it automatically when they first add a book.11 Books can then be attached to that attic, listed, counted, or marked as received in the pivot table, which suggests a collectible or progress-gated reading queue rather than a plain wishlist.11

The Secret Vault and Secret Books layer adds an economy mechanic on top of that system.12 Secret books can be created individually or in bulk, priced, listed, and then purchased by users using their accumulated reading_rank instead of traditional payment.12 If the user has enough rank, the backend deducts the price, creates a vault if one does not exist yet, and attaches the purchased book to that vault.12

System Current purpose
Secret Attic Personal collection of saved books before or during reading
Secret Vault Personal storage of purchased secret books
Secret Books Purchasable premium books with mutable prices
Reading rank In-app currency earned by reading actions

Notes system

The notes subsystem lets authenticated users create annotations tied to books.2 10 Creating a note requires text and book_id, and the note is saved against the authenticated user.10 The controller also supports updating existing notes, listing all notes, filtering notes by book, and deleting notes subject to policy checks.10

One important implementation detail is that viewAllNotes() returns all notes with eager-loaded user and book relations, not just the current user's notes.10 That is useful to document because it reflects the actual repository behavior rather than an assumed per-user privacy model.

Data model overview

The data model supports both standard reading and gamified progression. The migration set and model layout show dedicated tables for categories, books, notes, reading progress, reading streaks, secret attics, secret books, secret vaults, and the corresponding pivot tables that connect them.5 14

Model Role in the system
User Authenticated reader account with rank and streak fields
Book Standard book catalog entry
ReadingProgress Reading timeline between users and books
ReadingStreak Daily streak tracking
Note User-created annotation attached to a book
SecretAttic User's saved-book collection
SecretBook Purchasable premium/hidden book
SecretVault User-owned purchased-book vault

Local development

This is a standard Laravel repository from a setup perspective, even though the application logic is highly customized. The example environment file uses MySQL defaults and the usual Laravel application settings, so local development follows the normal Laravel workflow.13 15

Step Command
Install PHP dependencies composer install
Install JS dependencies npm install
Copy environment file cp .env.example .env
Generate app key php artisan key:generate
Configure database Edit .env with your MySQL credentials
Run migrations php artisan migrate
Start backend server php artisan serve
Start Vite dev server npm run dev

The example environment file expects values such as APP_NAME, APP_ENV, APP_KEY, APP_URL, DB_CONNECTION, DB_HOST, DB_PORT, DB_DATABASE, DB_USERNAME, and DB_PASSWORD for local development.15 The broader Laravel config also supports standard optional mail, Redis, AWS, queue, and broadcasting variables, but the repository's feature-specific logic does not currently introduce separate custom environment variables beyond those framework settings.15

Current implementation notes

This README is intentionally written to reflect the repository as it exists now, including details maintainers may want to revisit later.

Topic Current state
Documentation status The previous README was still default Laravel boilerplate rather than project-specific documentation.
Auth credentials Login currently validates username and password, not email/password.
Logout route Logout is exposed without explicit route middleware even though the controller expects an authenticated user.
Soft delete route The route references softdeleteUser, while the controller defines softDelete, indicating a naming mismatch in current code.
Reading rewards Reading rank is incremented on start, finish, and note creation, making rank a central progression currency.
Content scraping The active scraping logic targets Project Gutenberg HTML pages and strips content after the boilerplate header.
Privacy quirks The notes listing endpoint currently returns all notes with related users and books.
Economy system Secret-book purchasing uses reading rank rather than external payment.

References

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors