The Lingo Switch aims to create a centralized repository for managing strings (language) used across multiple projects along with their related URLs. The system enables developers to define and manage strings for multiple languages, ensuring that strings do not have to be hardcoded into the system. This solution supports efficient string management across multiple projects and provides an interface to dynamically add, update, and toggle the visibility of strings (active/inactive).
- Multi-Language Support: Manage strings in multiple languages, such as English, French, and German.
- Project-Based Management: String keys are organized by project and can be associated with specific URLs.
- Dynamic String Management: Add, edit, and delete strings from a centralized system, preventing hardcoding.
- String Status Toggling: Mark strings as active or inactive without deleting them, controlling visibility without removal.
- Security: Role-based access to the system, authenticated via username and password.
- History Tracking: Track when strings were created, updated, and deleted, along with the user responsible for the action.
- Bonus Features: JSON compressed output for string queries to optimize bandwidth usage.
- Installation and Setup
- Technology Stack
- System Design
- UI Design
- Functionality
- Usage
- Security
- Testing and Debugging
- Future Enhancements
- Contributing
- License
- Frontend: Angular 17, Angular Material, SCSS
- Backend: Node.js 20, Express.js, Sequelize
- Database: MySQL
- Authentication: JWT (JSON Web Tokens)
- Node.js
- MySQL
- Angular CLI
- Clone the repository:
git clone https://github.com/jo-walker/LingoSwitch.git
- Navigate to app root dir and install dependencies:
npm install
- start the server
npm start
-
Get all strings:
GET /api/strings
URL: /api/strings Method: GET Description: Retrieve all strings from the database. -
Add a new string:
POST /api/strings
URL: /api/strings Method: POST Description: Add a new string to the database. Request Body: { "value": "Hello World", "language": "en", "urls": ["/home"] }
id:
Primary key (manual autoincrementation in the server logic)name:
Project namelanguages:
Array of supported languageshistory:
JSON object tracking creation and updates
+-----------+--------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +-----------+--------------+------+-----+---------+-------+ | id | varchar(5) | NO | PRI | NULL | | | name | varchar(255) | NO | | NULL | | | languages | json | NO | | NULL | | | history | json | YES | | NULL | | +-----------+--------------+------+-----+---------+-------+
id:
Primary key (auto-incremented)urlId:
Foreign key to associate with URLseng_us:
English stringfr:
French stringde:
German stringactive:
Boolean flag for string status (active/inactive)history:
JSON object tracking changes to the string +-----------+------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +-----------+------------+------+-----+---------+----------------+ | id | int | NO | PRI | NULL | auto_increment | | urlId | varchar(4) | YES | MUL | NULL | | | eng_us | text | YES | | NULL | | | fr | text | YES | | NULL | | | de | text | YES | | NULL | | | userId | int | YES | MUL | NULL | | | projectId | varchar(5) | YES | MUL | NULL | | | history | json | YES | | NULL | | | active | tinyint(1) | YES | | 1 | | +-----------+------------+------+-----+---------+----------------+
id:
Primary key (uses UUUI to achieve UXXX logical manual incremental logic)url:
The URL where the string is usedhistory:
JSON object tracking changes to the uRL +-----------+--------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +-----------+--------------+------+-----+---------+-------+ | id | varchar(4) | NO | PRI | NULL | | | url | varchar(255) | NO | | NULL | | | history | json | YES | | NULL | | | projectId | varchar(5) | YES | MUL | NULL | | +-----------+--------------+------+-----+---------+-------+
id:
Primary key (auto-incremented)username:
username of the userpassword
decrypted passwordhistory:
JSON object tracking changes to the user info +----------+--------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +----------+--------------+------+-----+---------+----------------+ | id | int | NO | PRI | NULL | auto_increment | | username | varchar(255) | NO | UNI | NULL | | | password | varchar(255) | NO | | NULL | | | history | json | YES | | NULL | | +----------+--------------+------+-----+---------+----------------+
POST /api/auth/register
POST /api/auth/login
GET /api/projects
POST /api/projects
PUT /api/projects/:id
GET /api/strings
GET /api/strings/:id
POST /api/strings
PUT /api/strings/:id
PUT /api/strings/toggle-status/:id
DELETE /api/strings/:id
GET /api/urls
POST /api/urls
PUT /api/urls/:id
GET /api/strings/compressed?url=<URL>&language=<lang_code>
: Returns compressed JSON data for efficient string retrieval.
The user interface is developed using Angular 17 with PrimeNG components for a modern and responsive experience. The UI supports the following:
- Projects Page: List all projects and allows adding new projects.
- Strings Page: Display all strings with a filter for active/inactive status. Strings can be added, edited, deleted, or toggled between active/inactive.
- Responsive Design: The layout adapts for smaller screens, ensuring usability across devices.
- Design Style: The interface uses a minimalist design with soft colors for readability and consistency.
- Users can add strings in multiple languages.
- Existing strings can be updated or soft-deleted (marked inactive).
- String validation ensures no duplicate strings (case insensitive).
- The status of strings can be toggled between active and inactive without deleting them from the database.
- A filter is provided on the UI to show All, Active, or Inactive strings based on user preference.
- Developers can query the string database via an API, fetching strings by URL and language in a compressed JSON format to optimize bandwidth.
- Navigate to the Projects page.
- Click "Add Project" to define a new project and its supported languages.
- Once the project is added, you can manage the associated strings and URLs.
- Go to the Strings page.
- Add new strings, specify their languages, and associate them with URLs.
- Use the Status Filter to filter strings by active/inactive status.
Developers can use the API to query strings by URL and language. The results will be returned in a compressed JSON format to optimize bandwidth.
- Authentication is implemented using JWT (JSON Web Tokens). Access to the system is secured via username and password. Only authenticated users can create, update, and delete projects or strings.
- Environment variables are used to handle sensitive data.
- Error handling and validations are integrated into both the frontend and backend.
- Debugging and testing were performed using Postman to validate API responses.
- Role-Based Access Control (RBAC): Implement user roles to restrict access to certain parts of the system.
- String Categorization: Enable categorization of strings for better management.
- Translation Automation: Integrate automatic translation APIs to suggest translations for missing language fields.
- UI Design: Continue to refine the user interface for a more professional appearance and enhanced accessibility.
- Branching: Utilized feature branches for individual tasks and features. Merged completed branches into the default branch after testing to ensure a clean and stable codebase.
- Deployment: Managed deployment on the default branch after successfully merging feature branches.
- Project Dashboard: Used GitHub's Project Dashboard to track tasks, manage the backlog, and prioritize work. - This helped stay on top of tasks that are required.
Overall, I conclude the project achieves the goal of the task and may need enhancements for UI, advanced security features, and DB schema that can store more than 3 languages.
Contributions are welcome! Please feel free to submit a pull request or file an issue if you encounter any bugs or have suggestions for improvements.
- Fork the repository.
- Create a new branch (
git checkout -b main
). - Make your changes.
- Submit a pull request.