Skip to content

topboyasante/aaccraa

Repository files navigation

ReadNovls

A modern open-source platform for reading and writing novels, stories, and serialized fiction. Built with NestJS, SvelteKit, and PostgreSQL.

License PRs Welcome

Table of Contents

About

ReadNovls is a full-featured platform similar to Wattpad or Royal Road, where authors can publish their stories chapter by chapter, and readers can discover, read, and engage with content through likes, views, and comments.

Features

  • User Management

    • Email/password authentication
    • Google OAuth integration
    • JWT-based session management
    • User profiles and account management
  • Story Management

    • Create single stories or multi-part series
    • Rich text editor with TipTap
    • Draft and publish functionality
    • Cover image uploads with Cloudinary
    • Genre and tag categorization
    • Mature content flagging
    • Featured stories
  • Reader Engagement

    • Like and view tracking with rate limiting
    • Comment system
    • Story discovery and search
    • Responsive reading experience
  • Admin Features

    • Content moderation
    • User management
    • Featured story curation
    • Analytics dashboard
  • Infrastructure

    • Background job processing with BullMQ
    • Redis caching
    • Email notifications
    • Full-text search
    • RESTful API with Swagger documentation
    • Health checks and monitoring

Tech Stack

Backend (API)

  • Framework: NestJS 11
  • Database: PostgreSQL 16 with TypeORM
  • Cache/Queue: Redis 7 with BullMQ
  • Authentication: Passport.js with JWT
  • Email: Resend / Nodemailer
  • File Upload: Cloudinary
  • Security: Helmet, CSRF protection, rate limiting
  • Logging: Pino
  • API Docs: Swagger/OpenAPI

Frontend (Web & Admin)

  • Framework: SvelteKit 2 with Svelte 5
  • Styling: TailwindCSS 4
  • UI Components: Bits UI
  • Rich Text: TipTap
  • Forms: Formsnap with Zod validation
  • HTTP Client: Axios
  • Testing: Vitest, Playwright

Infrastructure

  • Containerization: Docker with Docker Compose
  • Package Manager: pnpm workspaces
  • Language: TypeScript

Architecture

This is a pnpm workspace monorepo with the following structure:

aaccraa/
β”œβ”€β”€ apps/
β”‚   β”œβ”€β”€ api/          # NestJS REST API
β”‚   β”œβ”€β”€ web/          # SvelteKit web application
β”‚   └── admin/        # SvelteKit admin panel
└── packages/         # Shared packages (future)

API Architecture

The API follows NestJS best practices with a modular architecture:

  • src/modules/ - Feature modules (auth, users, stories, etc.)
  • src/common/ - Shared utilities, decorators, filters, interceptors
  • src/core/ - Core functionality (database, docs, mail, queue, redis, security)
  • src/providers/ - External service integrations (Cloudinary, AutoSend)

Path aliases are configured for clean imports:

  • @/modules/* β†’ src/modules/*
  • @/common/* β†’ src/common/*
  • @/core/* β†’ src/core/*
  • @/providers/* β†’ src/providers/*

Frontend Architecture

Both web and admin apps follow a similar structure:

  • src/lib/ - Shared components, utilities, types, hooks
  • src/modules/ - Feature-specific components and logic
  • src/routes/ - SvelteKit file-based routing with route groups
  • src/services/ - API service layer
  • src/styles/ - Global styles

Getting Started

Prerequisites

  • Node.js >= 20.0.0
  • pnpm >= 9.0.0
  • Docker and Docker Compose (for database and Redis)
  • PostgreSQL 16+ (if not using Docker)
  • Redis 7+ (if not using Docker)

Installation

  1. Clone the repository

    git clone https://github.com/yourusername/aaccraa.git
    cd aaccraa
  2. Install dependencies

    pnpm install

Environment Configuration

1. API Environment Setup

Copy the example environment file:

cp apps/api/.env.example apps/api/.env

Edit apps/api/.env and configure:

Required:

# Server
PORT=3002
FRONTEND_URL=http://localhost:5173

# JWT Secrets (generate with: node -e "console.log(require('crypto').randomBytes(64).toString('hex'))")
JWT_SECRET=your-strong-secret-here
JWT_REFRESH_SECRET=your-different-strong-secret-here
CSRF_SECRET=your-csrf-secret-here
ANONYMOUS_VIEW_SECRET=your-view-secret-here

# Database
DB_HOST=localhost
DB_PORT=5433
DB_USER=aaccraa
DB_PASSWORD=your-secure-password
DB_NAME=aaccraa

# Redis
REDIS_HOST=localhost
REDIS_PORT=6380
REDIS_PASSWORD=your-secure-redis-password

# Email (AutoSend or other provider)
AUTOSEND_API_KEY=your-api-key
MAIL_FROM=noreply@yourdomain.com

Optional:

# Google OAuth (for social login)
GOOGLE_CLIENT_ID=your-client-id
GOOGLE_CLIENT_SECRET=your-client-secret
GOOGLE_CALLBACK_URL=http://localhost:3002/api/v1/auth/google/callback

2. Web Environment Setup

cp apps/web/.env.example apps/web/.env

Edit apps/web/.env:

PUBLIC_API_URL=http://localhost:3002

3. Admin Environment Setup

cp apps/admin/.env.example apps/admin/.env

Edit apps/admin/.env:

PUBLIC_API_URL=http://localhost:3002

Database Setup

Option 1: Using Docker (Recommended)

Start PostgreSQL and Redis with Docker Compose:

cd apps/api
docker-compose up -d

This starts:

  • PostgreSQL on port 5433
  • Redis on port 6380

Option 2: Local Installation

Install PostgreSQL 16+ and Redis 7+ locally and update the connection details in your .env file.

Run Migrations

cd apps/api
pnpm build
pnpm migration:run

Seed Database (Optional)

pnpm seed

Development

Run All Services

From the root directory:

pnpm dev

This starts:

Run Individual Services

# API only
pnpm dev:api

# Web only
pnpm dev:web

# Admin only
pnpm dev:admin

API Documentation

When the API is running, access Swagger documentation at:

http://localhost:3002/api/docs

Health Check

http://localhost:3002/api/v1/health

Testing

Run All Tests

pnpm test

API Tests

cd apps/api
pnpm test           # Unit tests
pnpm test:watch     # Watch mode
pnpm test:cov       # Coverage report
pnpm test:e2e       # E2E tests

Web Tests

cd apps/web
pnpm test:unit      # Unit tests
pnpm test:e2e       # Playwright E2E tests

Admin Tests

cd apps/admin
pnpm test:unit      # Unit tests
pnpm test:e2e       # Playwright E2E tests

Deployment

Production Build

pnpm build

Docker Deployment

  1. Configure production environment

    cp .env.production.example .env.production
  2. Edit .env.production with production values:

    • Generate strong secrets for JWT tokens
    • Set strong database passwords
    • Configure your domain for FRONTEND_URL
    • Set up email service credentials
  3. Build and deploy

    docker-compose -f docker-compose.prod.yml up -d --build

This starts:

  • PostgreSQL (internal only)
  • Redis (internal only)
  • API on port 3002
  • Web on port 3000

Run Production Migrations

docker exec -it readnovls-api-prod pnpm migration:run:prod

Viewing Logs

# View all logs
docker-compose -f docker-compose.prod.yml logs -f

# View specific service logs
docker-compose -f docker-compose.prod.yml logs -f api
docker-compose -f docker-compose.prod.yml logs -f web

Project Structure

aaccraa/
β”œβ”€β”€ apps/
β”‚   β”œβ”€β”€ api/                    # NestJS Backend
β”‚   β”‚   β”œβ”€β”€ src/
β”‚   β”‚   β”‚   β”œβ”€β”€ common/         # Shared utilities
β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ decorators/ # Custom decorators
β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ entities/   # Base entities
β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ filters/    # Exception filters
β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ interceptors/
β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ middleware/
β”‚   β”‚   β”‚   β”‚   └── utils/
β”‚   β”‚   β”‚   β”œβ”€β”€ core/           # Core functionality
β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ config/     # Configuration
β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ database/   # TypeORM & migrations
β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ docs/       # Swagger setup
β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ health/     # Health checks
β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ logger/     # Pino logger
β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ mail/       # Email service
β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ queue/      # BullMQ jobs
β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ redis/      # Redis client
β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ scheduler/  # Cron jobs
β”‚   β”‚   β”‚   β”‚   └── security/   # Security config
β”‚   β”‚   β”‚   β”œβ”€β”€ modules/        # Feature modules
β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ accounts/   # Account management
β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ admin/      # Admin features
β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ auth/       # Authentication
β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ comments/   # Comment system
β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ profile/    # User profiles
β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ stories/    # Story management
β”‚   β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ dto/
β”‚   β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ entities/
β”‚   β”‚   β”‚   β”‚   β”‚   └── services/
β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ upload/     # File uploads
β”‚   β”‚   β”‚   β”‚   └── users/      # User management
β”‚   β”‚   β”‚   β”œβ”€β”€ providers/      # External services
β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ autosend/   # Email provider
β”‚   β”‚   β”‚   β”‚   └── cloudinary/ # Image hosting
β”‚   β”‚   β”‚   └── main.ts         # Application entry
β”‚   β”‚   β”œβ”€β”€ test/               # E2E tests
β”‚   β”‚   β”œβ”€β”€ .env.example
β”‚   β”‚   β”œβ”€β”€ docker-compose.yml
β”‚   β”‚   └── package.json
β”‚   β”‚
β”‚   β”œβ”€β”€ web/                    # SvelteKit Web App
β”‚   β”‚   β”œβ”€β”€ src/
β”‚   β”‚   β”‚   β”œβ”€β”€ lib/            # Shared code
β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ assets/     # Images, fonts, etc.
β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ axios/      # Axios config
β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ components/ # Reusable components
β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ hooks/      # Custom hooks
β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ types/      # TypeScript types
β”‚   β”‚   β”‚   β”‚   └── utils/      # Utility functions
β”‚   β”‚   β”‚   β”œβ”€β”€ modules/        # Feature modules
β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ auth/       # Auth components
β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ comments/   # Comment components
β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ profile/    # Profile components
β”‚   β”‚   β”‚   β”‚   └── stories/    # Story components
β”‚   β”‚   β”‚   β”œβ”€β”€ routes/         # SvelteKit routes
β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ (auth)/     # Auth route group
β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ (system)/   # Public routes
β”‚   β”‚   β”‚   β”‚   └── sitemap.xml/
β”‚   β”‚   β”‚   β”œβ”€β”€ services/       # API services
β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ auth/
β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ comments/
β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ stories/
β”‚   β”‚   β”‚   β”‚   └── upload/
β”‚   β”‚   β”‚   └── styles/         # Global styles
β”‚   β”‚   β”œβ”€β”€ static/             # Static assets
β”‚   β”‚   β”œβ”€β”€ .env.example
β”‚   β”‚   └── package.json
β”‚   β”‚
β”‚   └── admin/                  # SvelteKit Admin Panel
β”‚       β”œβ”€β”€ src/
β”‚       β”‚   β”œβ”€β”€ lib/            # Shared code
β”‚       β”‚   β”‚   β”œβ”€β”€ assets/
β”‚       β”‚   β”‚   β”œβ”€β”€ axios/
β”‚       β”‚   β”‚   β”œβ”€β”€ components/
β”‚       β”‚   β”‚   β”œβ”€β”€ hooks/
β”‚       β”‚   β”‚   β”œβ”€β”€ types/
β”‚       β”‚   β”‚   └── utils/
β”‚       β”‚   β”œβ”€β”€ modules/        # Feature modules
β”‚       β”‚   β”‚   └── auth/
β”‚       β”‚   β”œβ”€β”€ routes/         # SvelteKit routes
β”‚       β”‚   β”‚   β”œβ”€β”€ (admin)/    # Admin route group
β”‚       β”‚   β”‚   └── (auth)/     # Auth route group
β”‚       β”‚   β”œβ”€β”€ services/       # API services
β”‚       β”‚   β”‚   β”œβ”€β”€ analytics/
β”‚       β”‚   β”‚   β”œβ”€β”€ auth/
β”‚       β”‚   β”‚   β”œβ”€β”€ stories/
β”‚       β”‚   β”‚   └── users/
β”‚       β”‚   └── styles/         # Global styles
β”‚       β”œβ”€β”€ static/
β”‚       β”œβ”€β”€ .env.example
β”‚       └── package.json
β”‚
β”œβ”€β”€ packages/                   # Shared packages (future)
β”œβ”€β”€ docker-compose.prod.yml     # Production deployment
β”œβ”€β”€ .env.production.example
β”œβ”€β”€ pnpm-workspace.yaml
β”œβ”€β”€ package.json
└── README.md

API Documentation

Authentication Endpoints

POST   /api/v1/auth/register
POST   /api/v1/auth/login
POST   /api/v1/auth/refresh
POST   /api/v1/auth/logout
GET    /api/v1/auth/google
GET    /api/v1/auth/google/callback

Story Endpoints

GET    /api/v1/stories
GET    /api/v1/stories/:id
POST   /api/v1/stories
PUT    /api/v1/stories/:id
DELETE /api/v1/stories/:id
POST   /api/v1/stories/:id/publish
POST   /api/v1/stories/:id/like
POST   /api/v1/stories/:id/view

User Endpoints

GET    /api/v1/users/me
PUT    /api/v1/users/me
GET    /api/v1/users/:id

For complete API documentation, run the API and visit /api/docs.

Available Scripts

Root Level

pnpm dev              # Run API and web in parallel
pnpm dev:api          # Run API only
pnpm dev:web          # Run web only
pnpm dev:admin        # Run admin only
pnpm build            # Build all packages
pnpm test             # Run tests in all packages
pnpm lint             # Lint all packages
pnpm format           # Format code with Prettier

API Scripts

pnpm build            # Build the application
pnpm dev              # Start in watch mode
pnpm start:prod       # Start production build
pnpm test             # Run unit tests
pnpm test:e2e         # Run E2E tests
pnpm lint             # Lint and fix
pnpm migration:generate  # Generate new migration
pnpm migration:run    # Run migrations
pnpm migration:revert # Revert last migration
pnpm seed             # Seed database

Web/Admin Scripts

pnpm dev              # Start dev server
pnpm build            # Build for production
pnpm preview          # Preview production build
pnpm test:unit        # Run unit tests
pnpm test:e2e         # Run E2E tests
pnpm check            # Type-check
pnpm lint             # Lint code
pnpm format           # Format code

Database Migrations

Create a New Migration

After modifying entities:

cd apps/api
pnpm migration:generate src/core/database/migrations/YourMigrationName

Run Migrations

pnpm migration:run

Revert Last Migration

pnpm migration:revert

View Migration Status

pnpm migration:show

Contributing

We welcome contributions! Here's how you can help:

  1. Fork the repository
  2. Create a feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'feat: add amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

Contribution Guidelines

  • Follow the existing code style
  • Write tests for new features
  • Update documentation as needed
  • Use conventional commits (feat, fix, docs, style, refactor, test, chore)
  • Ensure all tests pass before submitting PR
  • Keep PRs focused on a single feature or fix

Code Style

  • TypeScript: Use TypeScript for all new code
  • ESLint & Prettier: Follow the configured linting and formatting rules
  • Path Aliases: Use path aliases for imports in the API (@/modules/*, @/common/*, etc.)
  • Naming Conventions: Use descriptive variable and function names
  • Comments: Add JSDoc comments for public APIs and complex logic

Reporting Issues

  • Use the GitHub issue tracker
  • Check if the issue already exists
  • Provide a clear description and steps to reproduce
  • Include relevant logs or screenshots
  • Specify your environment (OS, Node version, etc.)

Development Workflow

  1. Create a new branch from master
  2. Make your changes
  3. Run tests locally: pnpm test
  4. Run linting: pnpm lint
  5. Format code: pnpm format
  6. Commit with conventional commit messages
  7. Push and create a PR

Security

If you discover a security vulnerability, please email security@readnovls.com instead of using the issue tracker.

License

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

Acknowledgments

Support


Made with ❀️ by the ReadNovls community

About

A modern open-source platform for reading and writing novels, stories, and serialized fiction. Built with NestJS, SvelteKit, and PostgreSQL.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors