TDS Bookmark Manager is a modern, full-stack application designed to help you organize, find, and use your web links like never before.
Built with a modern tech stack within a professional monorepo architecture powered by Nx.
This project is more than just a bookmark manager. It is a complete platform that offers a clean and intuitive user interface, a powerful and secure backend, and advanced features such as quick-adding links via webhooks or a custom bookmarklet. The entire project is packaged in a Dockerized environment for consistent development and deployment.
- Secure Authentication: JWT-based system with password hashing using
bcrypt. - Role-Based Access Control (RBAC): Differentiated roles for
UserandAdminwith protected routes and functionalities. - Full Bookmark Management: Complete CRUD (Create, Read, Update, Delete) operations for bookmarks.
- Hierarchical Organization: Organize your bookmarks into nested folders and subfolders.
- Usage Statistics: View analytics on your bookmark usage, including click counts and most-used links.
- Quick Add (Webhook & Bookmarklet): Easily add bookmarks from any browser using a unique webhook URL or a bookmarklet.
- Multi-language Support: Fully internationalized interface supporting English and Spanish.
- Admin Panel: A dedicated section for administrators to manage users and view global statistics.
- Dockerized Environment: The entire stack, including the PostgreSQL database, is managed via Docker for maximum consistency between environments.
The project is organized as a monorepo managed with Nx and npm workspaces.
| Area | Technology |
|---|---|
| Monorepo | Nx, npm workspaces |
| Backend | NestJS, TypeORM, PostgreSQL, Passport.js, Pino (for logging), Jest |
| Frontend | React, Vite, TypeScript, Tailwind CSS, Zustand (state), React Router, i18next, Vitest, React Testing Library, Playwright (E2E) |
| Database | PostgreSQL (managed with Docker) |
| DevOps | Docker & Docker Compose, ESLint, Prettier, GitHub Actions |
The monorepo is organized as follows, promoting code reuse and separation of concerns:
tds-bookmark-manager-platform/
βββ .github/workflows/
β βββ docker-publish.yml # CI workflow for the 'main' branch
β βββ release.yml # Release workflow for Git tags
βββ apps/
β βββ backend/
β β βββ tds-bookmark-manager-api/ # The NestJS API
β β βββ tds-bookmark-manager-api-e2e/ # E2E tests for the API
β βββ ui/
β βββ tds-bookmark-manager-ui/ # The React application
β βββ tds-bookmark-manager-ui-e2e/ # E2E tests for the UI with Playwright
βββ libs/
β βββ tds-bm-common/ # Shared library (DTOs, interfaces)
βββ docker-compose.yml # Docker Compose file for production
βββ docker-compose.develop.yml # Docker Compose file for development
βββ nx.json # Main Nx configuration
βββ package.json # Workspace dependencies and scripts
Follow these steps to get the full development environment running on your local machine.
- Node.js (v22 or higher recommended)
- npm (v7 or higher, included with Node.js)
- Docker and Docker Compose
-
Clone the repository:
git clone [https://github.com/d-lacreme/tds-bookmark-manager-platform.git](https://github.com/d-lacreme/tds-bookmark-manager-platform.git) cd tds-bookmark-manager-platform -
Install dependencies: From the project root, install all dependencies for all applications and libraries.
npm install
-
Configure Environment Variables for the API: The API requires an
.envfile to function. Create a file namedapps/backend/tds-bookmark-manager-api/.env.developmentand paste the following content.# apps/backend/tds-bookmark-manager-api/.env.development # Application Environment NODE_ENV=development APP_HOST=localhost APP_PORT=3000 APP_PROTOCOL=http APP_NAME=TDS Bookmark Manager API # Rate Limiting Configuration GLOBAL_RATE_LIMIT_TTL=60000 GLOBAL_RATE_LIMIT_LIMIT=100 # JWT Configuration # IMPORTANT: Use a long and secure secret in a real environment. JWT_SECRET=this-is-a-very-long-and-secure-development-secret JWT_EXPIRES_IN=1d # PostgreSQL Database Variables # These match the ones in docker-compose.develop.yml POSTGRES_HOST=localhost POSTGRES_PORT=5432 POSTGRES_USER=testuser POSTGRES_PASSWORD=testpassword POSTGRES_DB=tds_bookmarks_db
-
Start Docker services: This command will spin up the PostgreSQL database container.
npm run docker:dev:up
-
Run Database Migrations: With the database running, apply the initial schema.
npm run migration:run
-
Start the Development Servers: You can start the API and UI simultaneously with a single command.
npm run start:all:dev
Alternatively, in separate terminals:
- Terminal 1 (API):
npm run start:api:dev - Terminal 2 (UI):
npm run start:ui:dev
- Terminal 1 (API):
You're all set! The React application will be available at http://localhost:4200 and the NestJS API at http://localhost:3000.
These are the most important scripts defined in the root package.json:
| Script | Description |
|---|---|
start:all:dev |
Starts the API and UI in development mode simultaneously. |
build:all |
Builds the common library, the API, and the UI for production. |
test:all |
Runs all unit/component tests for the API and UI. |
docker:dev:up |
Starts the Docker containers defined in docker-compose.develop.yml. |
docker:build:versioned |
Builds versioned Docker images based on the package.json version. |
release:tag |
Creates a custom-formatted Git tag based on the package.json version. |
migration:run |
Runs pending migrations on the database. |
migration:generate |
Generates a new migration file from entity changes. |
This project uses GitHub Actions to automate the build and release process. The workflow is split into two distinct parts to handle continuous integration and versioned releases separately.
This workflow is defined in .github/workflows/docker-publish.yml.
- Trigger: Automatically runs on every push to the
mainbranch. - Purpose: To build and publish "bleeding-edge" images of the services that were affected by the changes in the push.
- Efficiency: It uses
npx nx affectedto intelligently detect which projects (api,ui,migrations) have changed and only builds images for them. This saves significant time and resources. - Image Naming: Publishes images to GitHub Container Registry (GHCR) with the specific names (
The-Dave-Stack/tds-bookmark-manager-api, etc.). - Tagging Strategy: Images are tagged with:
latest: Always points to the most recent commit onmain.<sha>: The short commit hash (e.g.,a1b2c3d) for perfect traceability.
This workflow is defined in .github/workflows/release.yml.
- Trigger: Runs only when a new Git tag matching the pattern
v*.*.*/*(e.g.,v0.1.x/0.1.0) is pushed to the repository. - Purpose: To create and publish official, stable, and immutable releases of the entire application suite (UI, API, and Migrations).
- How to Trigger a Release: This is a manual process made easy with an npm script. Do not use
npm versionfor releases.- Update Version: Manually edit the
versionfield in the rootpackage.jsonfile. - Commit Change: Commit the updated
package.json.git add package.json git commit -m "chore(release): bump version to 0.1.0" - Create Custom Tag: Run the helper script to create the correctly formatted Git tag.
npm run release:tag
- Push to GitHub: Push your commit and the new tag to trigger the workflow.
git push && git push --tags
- Update Version: Manually edit the
- Tagging Strategy: The workflow extracts the standard version from the custom Git tag. Docker images are then published with standard, useful semantic version tags:
1.0.1(full version)1.0(minor version)1(major version)latest
The project is set up with unit, integration, and E2E tests.
- Run UI Tests (Vitest):
npm run test:ui
- Run API Tests (Jest):
npm run test:api
- Run UI E2E Tests (Playwright):
Ensure the application is running (
npm run start:ui:dev) and then execute:npx nx e2e @tds/tds-bookmark-manager-ui-e2e
Contributions are welcome! If you want to improve the project, please feel free to submit a Pull Request.
- Fork the Project.
- Create your Feature Branch (
git checkout -b feature/AmazingFeature). - Commit your Changes (
git commit -m 'Add some AmazingFeature'). - Push to the Branch (
git push origin feature/AmazingFeature). - Open a Pull Request.
Distributed under the MIT License. See the LICENSE file for more information.