From ccfc0b3e94f4ad7a9d167f707110753f7585e2ca Mon Sep 17 00:00:00 2001 From: siversm Date: Mon, 9 Nov 2026 12:31:18 +0100 Subject: [PATCH] docs: expand sustainability documentation Add detailed documentation covering data transfer, caching, SQLite, relational storage, trade-offs, limitations, and future improvements. Co-authored-by: Copilot GPT Luna 5.6 (Spelling and Formatting, fact checking) --- docs/Sustainability.md | 91 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 91 insertions(+) create mode 100644 docs/Sustainability.md diff --git a/docs/Sustainability.md b/docs/Sustainability.md new file mode 100644 index 0000000..17c5a3b --- /dev/null +++ b/docs/Sustainability.md @@ -0,0 +1,91 @@ +# Sustainability choices + +We have made several choices that help reduce unnecessary data transfer, processing, +and storage. In this context, sustainability means using fewer computing resources +while still providing the required functionality and a responsive user experience. + +## Reducing data transfer + +### Cursor-based pagination + +The GraphQL API uses cursor-based pagination to retrieve Pokémon in small pages +instead of loading the entire dataset at once. The server limits each request to +100 results and returns an `endCursor` together with page indicators. The client +can then request the next part of the dataset when the user navigates. + +This reduces the amount of data transferred and processed for each interaction, +especially when searching or browsing a larger dataset. It also avoids making +the browser render hundreds of cards that the user may never view. The +implementation is in `project2/server/schema.ts` and is used by the query in +`project2/src/App.tsx`. + +### Server-side search, filtering, and sorting + +Search, type filtering, and sorting are performed by the GraphQL server and +translated into database queries. The client therefore receives only the +matching page of results instead of downloading the complete dataset and +filtering it in the browser. This reduces both network traffic and client-side +processing. + +### Apollo client cache + +The frontend uses Apollo Client's `InMemoryCache`. Responses can be reused by +Apollo when the same query data is requested again, which can reduce repeated +requests and processing during a browsing session. The cache is configured in +`project2/src/main.tsx`. + +## Reducing processing and storage + +### SQLite database + +SQLite stores the application's data in a single lightweight database file. This +avoids the overhead of running a separate database server for this project while +still providing structured queries through Apollo GraphQL. A local database is +appropriate for the project's scale and deployment model, where a separate +database service would add operational and resource overhead. + +### Relational data structure + +Pokémon, abilities, types, and ratings are stored in separate related tables. +Separating these concerns keeps the main Pokémon records focused and allows +ratings to be updated without rewriting the rest of a Pokémon record. Foreign +keys and a composite primary key for ratings also prevent invalid or duplicate +rating records. + +This is a relational structure rather than complete deduplication: ability and +type values are currently stored in rows associated with each Pokémon. Further +normalization could reduce repeated names if the dataset grows substantially. +The schema and constraints are defined in `project2/server/db.ts`. + +### Seed-once database initialization + +The server checks whether the database already contains Pokémon before fetching +and inserting seed data. Existing data is reused on later starts, avoiding +repeated API requests and repeated processing. This behavior is implemented in +`project2/server/index.ts` and `project2/server/db.ts`. + +## Trade-offs and limitations + +These choices reduce unnecessary work for the current project, but they do not +eliminate resource usage: + +- The initial seed can still require a relatively large external API request. +- Pokémon images are loaded from an external image URL and are not currently + documented as having responsive variants or lazy loading. +- SQLite is lightweight for this deployment, but a larger multi-user system + could require a database service with stronger concurrency and scaling + characteristics. +- The current pagination API is forward-oriented: it exposes `after` and + `hasPreviousPage`, but does not expose a `before` or `last` argument for + directly requesting a previous page. + +## Possible future improvements + +If the dataset or traffic increases, we could measure and improve the system by: + +- adding indexes for the most common search, filter, and sort queries; +- lazy-loading images and serving appropriately sized image variants; +- caching seed data or using a controlled import process to reduce startup + requests; +- recording representative payload sizes, request counts, database size, and + load times to evaluate the effect of future changes.