- Clone the repo
- Copy
.env.exampleto.envand fill in the values - If you are using Ubuntu remember to turn off apache servers , serving their website on localhost
sudo systemctl stop apache2- Run the stack:
sudo docker compose up --build- App will be available at
http://localhost
frontend/— SvelteKit appbackend/— FastAPI appnginx/— Reverse proxy config
This is a full CRUD spreadsheet app , with formulas to calculate values dependent on different cells in the sheet implemented using Directed Acyclic Graphs and Kahn's Algorithm, sheets get locked when one user is editing to prevent merge conflicts, it also contains an admin page for management, with features to share sheets, the backend uses MongoDB to store users as well as sheet data and sheet locks
-
Client Side Formula Evaluation: To prevent load on backend servers and to prevent the backend from crashing in case some graph goes wrong, I decided to implement the formula engine on the client side, so that the app runs smoothly
-
httpOnly JWT Tokens: This was implemented as a security feature to avoid XSS attacks.
-
Locking with heartbeat pattern: This was implemented to keep the lock stable to a user if a user is online, and the expiry was kept 30s , so that if a user is not using the sheet for more than 30s we will consider that the user has moved on to some other task, and the heartbeat is 20s as a safety net , so that for someone whose internet is slow , the user should still be able to keep the lock.
-
Storing Cells as dictionary: This was done to optimise storage, not storing empty unused cells
-
MVC architecture on the backend : This was implemented so that if we require to switch the database from MongoDB to some other type , lets say PostgreSQL, we could do so easily in future, and to allow easier debugging and made adding features easier, also as it is implemented using MVC , anyone who reads the code , understands it almost instantly.
- No view-only mode for sheets locked by another user
- Formula engine uses
eval(), instead of a manually written evaluation function , this is a security tradeoff. - No real-time collaboration implemented.
- Task description at: https://winterdew.notion.site/Sports-Council-Tech-Team-Recruitment-Task-2026-35e0419730a18024bc99d5fccff7c7f0
- All API routes must go through
/api/ - Do not change port mappings in
docker-compose.yml - The app must start cleanly with
docker compose up --buildfor evaluation