---
title: Lynira
---

Lynira (hereinafter the "Application") is a link shortening service managed via a Discord bot with subscription-based access control and usage limits.

## 1. User Documentation

This section is for those interacting with a live instance of the Application.

### Overview
Lynira is a Discord-integrated URL shortening service that allows users to create shortened links through Discord commands. The service operates on a subscription model with different tiers offering varying numbers of shortened URLs.

### Discord Commands

#### `/add`
Creates a new shortened URL.
- **Parameters:**
  - `slug` (required): The short identifier for your URL (e.g., "my-link")
  - `url` (required): The full URL to redirect to (must be a valid HTTP/HTTPS URL)
- **Usage:** `/add slug:my-link url:https://example.com`
- **Result:** Creates a short URL accessible at `https://lynira.link/mylink`

#### `/list`
Displays all your active shortened URLs along with usage statistics.
- **Features:**
  - Shows current usage count vs. subscription limit
  - Provides clickable buttons to access Discord server
  - Lists all active short URLs with their destinations

#### `/remove`
Removes a shortened URL from your account.
- **Parameters:**
  - `slug` (required): The slug identifier to remove
- **Usage:** `/remove slug:mylink`
- **Note:** Removed slugs cannot be reused for security reasons

#### `/about`
Displays information about the Lynira service.

### Subscription Tiers
The service operates on multiple subscription tiers with different link limits:
- **Personal**: Limited number of links
- **Professional**: Higher link allowance
- **Business**: Business-level capacity
- **Organisation**: Significant link capacity
- **Enterprise**: Maximum link capacity

### Web Interface
The service provides several web pages:
- **Home page** (`/`): Service information
- **Error page** (`/error`): Displayed when system errors occur
- **Unsubscribed page** (`/unsub`): Shown when accessing links from unsubscribed users
- **Over limit page** (`/overlimit`): Displayed when users exceed their subscription limits
- **404 page** (`/404`): Shown for non-existent or deleted links

## 2. Technical Documentation

This section is for those interested in running their own instance of the Application.

### Architecture
Lynira is built using:
- **Node.js** with TypeScript
- **Discord.js** for Discord bot functionality
- **Fastify** web server for HTTP handling
- **Prisma** ORM for database operations
- **PostgreSQL** database (implied from Prisma usage)

### Core Components

#### Discord Bot (`src/index.ts`)
The main entry point that initializes:
- Prisma database connection
- Discord client with minimal intents
- Command processing system
- Web server instance

#### Web Server (`src/server/serve.ts`)
Fastify-based HTTP server providing:
- Static route handling
- Dynamic link redirection
- Subscription validation
- Usage limit enforcement
- Error page serving

#### Command System
Commands are modularized in `src/commands/`:
- `add.ts`: URL creation with validation and limit checking
- `list.ts`: User link listing with usage statistics
- `remove.ts`: Link deletion with ownership verification
- `about.ts`: Service information

#### Core Modules
- **`getEntitlement.ts`**: Discord entitlement validation
- **`getSkuLimit.ts`**: Subscription tier limit determination
- **`processCommand.ts`**: Command routing and execution
- **`sendUnintitledResponse.ts`**: Unsubscribed user handling

### Database Schema
The application uses Prisma with a `links` table containing:
- `id`: Primary key
- `slug`: Short URL identifier
- `url`: Target URL
- `userId`: Discord user ID
- `deleted`: Soft deletion flag

### Environment Configuration
Required environment variables:
- `BOT_TOKEN`: Discord bot token
- Database connection string (Prisma configuration)

### Security Features
- URL validation with regex patterns
- Reserved slug protection
- User ownership verification
- Subscription status validation
- Soft deletion for security
- Error handling and logging

### Deployment
- Production build via `npm run build`
- Prisma schema generation
- Environment-based configuration
- Port 5044 for web server
- 1Password integration for production secrets

## 3. Legal Documentation

This section is for expansions to our legal policies specific to the Application.

### Licensing
The Application is licensed under "Naomi's Public Licence" as indicated in the source code headers.

### Copyright
Copyright held by Naomi Carrigan (@nhcarrigan).

### Data Handling
The Application processes:
- Discord user IDs for authentication
- User-provided URLs for shortening
- Link access patterns for subscription enforcement
- Discord entitlement data for subscription validation

### Service Terms
- Users must maintain active Discord subscriptions
- Removed links cannot be reused for security
- Link editing is not permitted after creation
- Service availability depends on Discord API functionality

## 4. Contributing Documentation

This section is for documentation related to contributing to the Application's codebase.

### Development Setup
1. Clone the repository
2. Install dependencies: `pnpm install`
3. Set up Prisma database connection
4. Configure Discord bot token
5. Run development build: `npm run build`

### Code Standards
- **ESLint**: Enforced with `@nhcarrigan/eslint-config`
- **TypeScript**: Strict configuration via `@nhcarrigan/typescript-config`
- **Testing**: Currently no test suite (`npm test` placeholder)
- **Linting**: `npm run lint` with zero warnings policy

### Project Structure
```
src/
├── commands/          # Discord slash commands
├── config/           # Configuration files and handlers
├── interfaces/       # TypeScript interfaces
├── modules/          # Core business logic
├── server/           # Web server and HTML templates
└── utils/            # Utility functions
```

### Key Patterns
- Error handling with centralised `errorHandler`
- Logging via `@nhcarrigan/logger`
- Command pattern for Discord interactions
- Subscription-based access control
- Soft deletion for data safety

### Contribution Guidelines
- Follow existing code patterns and conventions
- Maintain TypeScript strict mode compliance
- Include proper error handling
- Add logging for important operations
- Respect subscription and security models

### Reserved Components
- Reserved slugs defined in `src/config/reservedSlugs.ts`
- Admin privileges for user ID `465650873650118659`
- Discord entitlement SKU IDs are environment-specific
