{"id":24543731,"url":"https://github.com/mushthak/essentialfeed","last_synced_at":"2026-05-19T17:04:32.291Z","repository":{"id":45729917,"uuid":"503675181","full_name":"mushthak/EssentialFeed","owner":"mushthak","description":"iOS Architecture and TDD Approach Case Study","archived":false,"fork":false,"pushed_at":"2023-10-08T12:15:39.000Z","size":4090,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-01-22T20:14:51.323Z","etag":null,"topics":["github-actions","swift","test-driven-development"],"latest_commit_sha":null,"homepage":"","language":"Swift","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mushthak.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null}},"created_at":"2022-06-15T08:14:36.000Z","updated_at":"2024-02-01T12:40:58.000Z","dependencies_parsed_at":"2023-02-10T12:45:16.036Z","dependency_job_id":null,"html_url":"https://github.com/mushthak/EssentialFeed","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mushthak%2FEssentialFeed","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mushthak%2FEssentialFeed/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mushthak%2FEssentialFeed/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mushthak%2FEssentialFeed/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mushthak","download_url":"https://codeload.github.com/mushthak/EssentialFeed/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243841229,"owners_count":20356446,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["github-actions","swift","test-driven-development"],"created_at":"2025-01-22T20:14:54.990Z","updated_at":"2026-05-19T17:04:22.277Z","avatar_url":"https://github.com/mushthak.png","language":"Swift","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Essential Feed App – Image Feed Feature\n\n[![CI- Test feed feature](https://github.com/mushthak/EssentialFeed/actions/workflows/github-actions.yml/badge.svg)](https://github.com/mushthak/EssentialFeed/actions/workflows/github-actions.yml)\n\n## Image Feed Feature Specs\n\n### Story: Customer requests to see their image feed\n\n### Narrative #1\n\n```\nAs an online customer\nI want the app to automatically load my latest image feed\nSo I can always enjoy the newest images of my friends\n```\n\n#### Scenarios (Acceptance criteria)\n\n```\nGiven the customer has connectivity\n When the customer requests to see their feed\n Then the app should display the latest feed from remote\n  And replace the cache with the new feed\n```\n\n### Narrative #2\n\n```\nAs an offline customer\nI want the app to show the latest saved version of my image feed\nSo I can always enjoy images of my friends\n```\n\n#### Scenarios (Acceptance criteria)\n\n```\nGiven the customer doesn't have connectivity\n  And there’s a cached version of the feed\n  And the cache is less than seven days old\n When the customer requests to see the feed\n Then the app should display the latest feed saved\n\nGiven the customer doesn't have connectivity\n  And there’s a cached version of the feed\n  And the cache is seven days old or more\n When the customer requests to see the feed\n Then the app should display an error message\n\nGiven the customer doesn't have connectivity\n  And the cache is empty\n When the customer requests to see the feed\n Then the app should display an error message\n```\n\n## Use Cases\n\n### Load Feed From Remote Use Case\n\n#### Data:\n- URL\n\n#### Primary course (happy path):\n1. Execute \"Load Image Feed\" command with above data.\n2. System downloads data from the URL.\n3. System validates downloaded data.\n4. System creates image feed from valid data.\n5. System delivers image feed.\n\n#### Invalid data – error course (sad path):\n1. System delivers invalid data error.\n\n#### No connectivity – error course (sad path):\n1. System delivers connectivity error.\n\n---\n\n### Load Feed Image Data From Remote Use Case\n\n#### Data:\n- URL\n\n#### Primary course (happy path):\n1. Execute \"Load Image Data\" command with above data.\n2. System downloads data from the URL.\n3. System validates downloaded data.\n4. System delivers image data.\n\n#### Cancel course:\n1. System does not deliver image data nor error.\n\n#### Invalid data – error course (sad path):\n1. System delivers invalid data error.\n\n#### No connectivity – error course (sad path):\n1. System delivers connectivity error.\n\n---\n\n### Load Feed From Cache Use Case\n\n#### Primary course:\n1. Execute \"Load Image Feed\" command with above data.\n2. System retrieves feed data from cache.\n3. System validates cache is less than seven days old.\n4. System creates image feed from cached data.\n5. System delivers image feed.\n\n#### Retrieval error course (sad path):\n1. System delivers error.\n\n#### Expired cache course (sad path): \n1. System delivers no feed images.\n\n#### Empty cache course (sad path): \n1. System delivers no feed images.\n\n---\n\n### Load Feed Image Data From Cache Use Case\n\n#### Data:\n- URL\n\n#### Primary course (happy path):\n1. Execute \"Load Image Data\" command with above data.\n2. System retrieves data from the cache.\n3. System delivers cached image data.\n\n#### Cancel course:\n1. System does not deliver image data nor error.\n\n#### Retrieval error course (sad path):\n1. System delivers error.\n\n#### Empty cache course (sad path):\n1. System delivers not found error.\n\n---\n\n### Validate Feed Cache Use Case\n\n#### Primary course:\n1. Execute \"Validate Cache\" command with above data.\n2. System retrieves feed data from cache.\n3. System validates cache is less than seven days old.\n\n#### Retrieval error course (sad path):\n1. System deletes cache.\n\n#### Expired cache course (sad path): \n1. System deletes cache.\n\n---\n\n### Cache Feed Use Case\n\n#### Data:\n- Image Feed\n\n#### Primary course (happy path):\n1. Execute \"Save Image Feed\" command with above data.\n2. System deletes old cache data.\n3. System encodes image feed.\n4. System timestamps the new cache.\n5. System saves new cache data.\n6. System delivers success message.\n\n#### Deleting error course (sad path):\n1. System delivers error.\n\n#### Saving error course (sad path):\n1. System delivers error.\n\n---\n\n### Cache Feed Image Data Use Case\n\n#### Data:\n- Image Data\n\n#### Primary course (happy path):\n1. Execute \"Save Image Data\" command with above data.\n2. System caches image data.\n3. System delivers success message.\n\n#### Saving error course (sad path):\n1. System delivers error.\n\n---\n\n## Flowchart\n\n![feed_flowchart](https://github.com/mushthak/EssentialFeed/assets/11793859/db9c7fea-9a18-4303-b350-632ada2d4d07)\n\n\n## Architecture\n\n![feed_architecture](https://github.com/mushthak/EssentialFeed/assets/11793859/58d1b97e-7465-4417-b4c6-4bf49017cfcf)\n\n\n## Model Specs\n\n### Feed Image\n\n| Property      | Type                |\n|---------------|---------------------|\n| `id`          | `UUID`              |\n| `description` | `String` (optional) |\n| `location`    | `String` (optional) |\n| `url`            | `URL`               |\n\n### Payload contract\n\n```\nGET *url* (TBD)\n\n200 RESPONSE\n\n{\n    \"items\": [\n        {\n            \"id\": \"a UUID\",\n            \"description\": \"a description\",\n            \"location\": \"a location\",\n            \"image\": \"https://a-image.url\",\n        },\n        {\n            \"id\": \"another UUID\",\n            \"description\": \"another description\",\n            \"image\": \"https://another-image.url\"\n        },\n        {\n            \"id\": \"even another UUID\",\n            \"location\": \"even another location\",\n            \"image\": \"https://even-another-image.url\"\n        },\n        {\n            \"id\": \"yet another UUID\",\n            \"image\": \"https://yet-another-image.url\"\n        }\n        ...\n    ]\n}\n```\n\n---\n\n## Image Comments Feature Specs\n\n### Story: Customer requests to see image comments\n\n### Narrative\n\n```\nAs an online customer\nI want the app to load image commments\nSo I can see how people are engaging with images in my feed\n```\n\n#### Scenarios (Acceptance criteria)\n\n```\nGiven the customer has connectivity\n When the customer requests to see comments on an image\n Then the app should display all comments for that image\n```\n\n```\nGiven the customer doesn't have connectivity\n When the customer requests to see comments on an image\n Then the app should display an error message\n```\n\n## Use Cases\n\n### Load Image Comments From Remote Use Case\n\n#### Data:\n- ImageID\n\n#### Primary course (happy path):\n1. Execute \"Load Image Comments\" command with above data.\n2. System loads data from remote service.\n3. System validates data.\n4. System creates comments from valid data.\n5. System delivers comments.\n\n#### Invalid data – error course (sad path):\n1. System delivers invalid data error.\n\n#### No connectivity – error course (sad path):\n1. System delivers connectivity error.\n\n---\n\n## Model Specs\n\n### Image Comment\n\n| Property          | Type                    |\n|-------------------|-------------------------|\n| `id`              | `UUID`                  |\n| `message` \t    | `String`\t\t\t      |\n| `created_at`      | `Date` (ISO8601 String) |\n| `author` \t\t\t| `CommentAuthorObject`   |\n\n### Image Comment Author\n\n| Property          | Type                |\n|-------------------|---------------------|\n| `username` \t    | `String`\t\t\t  |\n\n### Payload contract\n\n```\nGET /image/{image-id}/comments\n\n2xx RESPONSE\n\n{\n\t\"items\": [\n\t\t{\n\t\t\t\"id\": \"a UUID\",\n\t\t\t\"message\": \"a message\",\n\t\t\t\"created_at\": \"2020-05-20T11:24:59+0000\",\n\t\t\t\"author\": {\n\t\t\t\t\"username\": \"a username\"\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\t\"id\": \"another UUID\",\n\t\t\t\"message\": \"another message\",\n\t\t\t\"created_at\": \"2020-05-19T14:23:53+0000\",\n\t\t\t\"author\": {\n\t\t\t\t\"username\": \"another username\"\n\t\t\t}\n\t\t},\n\t\t...\n\t]\n}\n```\n\n---\n\n---\n\n## App Architecture\n\n![architecture-2](https://github.com/mushthak/EssentialFeed/assets/11793859/7c154a42-a87b-4a46-967c-4eccc93d5a32)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmushthak%2Fessentialfeed","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmushthak%2Fessentialfeed","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmushthak%2Fessentialfeed/lists"}