{"id":31661357,"url":"https://github.com/samlau95/gmis-flask-reddit","last_synced_at":"2026-02-18T19:02:00.338Z","repository":{"id":317792021,"uuid":"1068846448","full_name":"SamLau95/gmis-flask-reddit","owner":"SamLau95","description":"Starter app for GMIS student session","archived":false,"fork":false,"pushed_at":"2025-10-03T03:01:18.000Z","size":17,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-10-11T11:15:13.445Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"HTML","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/SamLau95.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,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-10-03T02:07:41.000Z","updated_at":"2025-10-03T03:01:21.000Z","dependencies_parsed_at":"2025-10-06T08:20:04.244Z","dependency_job_id":null,"html_url":"https://github.com/SamLau95/gmis-flask-reddit","commit_stats":null,"previous_names":["samlau95/gmis-flask-reddit"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/SamLau95/gmis-flask-reddit","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SamLau95%2Fgmis-flask-reddit","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SamLau95%2Fgmis-flask-reddit/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SamLau95%2Fgmis-flask-reddit/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SamLau95%2Fgmis-flask-reddit/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/SamLau95","download_url":"https://codeload.github.com/SamLau95/gmis-flask-reddit/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SamLau95%2Fgmis-flask-reddit/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29590684,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-18T18:54:29.675Z","status":"ssl_error","status_checked_at":"2026-02-18T18:50:50.517Z","response_time":162,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"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":[],"created_at":"2025-10-07T18:22:49.138Z","updated_at":"2026-02-18T19:02:00.332Z","avatar_url":"https://github.com/SamLau95.png","language":"HTML","funding_links":[],"categories":[],"sub_categories":[],"readme":"# CAHSI – GMiS – Student Generative AI Session\n\n**Activity: Reddit Clone in Flask**\n**October 2025**\n\n**Purpose**\n\nBuild a tiny Reddit-like site in Flask that supports voting, posting, and hiding\nitems—first in memory, then persisted to SQLite—while using an LLM as a thought\ncompanion (LPDP), not a code vending machine.\n\n**What you’ll practice**\n\n- Setting up a small Flask project and running it locally.\n- Server-side HTML forms and request/response flow (POST → redirect → GET).\n- Mutating in-memory state safely and rendering sorted views.\n- Incremental feature development with clear acceptance tests.\n- Finding and describing bugs in others’ code.\n- Adding persistence with sqlite3 and reasoning about data models.\n- Using the **LPDP prompts** to clarify, plan, debug, and reflect.\n\n**Tools \u0026 setup**\n\n- Work in **pairs** (Driver/Navigator; swap every ~15 minutes).\n- Stack: **Python 3.10+**, **Flask**, **uv**, any editor (VS Code recommended).\n- Basic HTML forms; no JS required.\n\n**Generative AI policy (read carefully)**\n\n- Use an LLM for **questions, planning, tiny nudges** (≤8 lines if code is essential; explain line‑by‑line).\n- **Do not** paste full solutions. You must own the design and tests.\n- Keep a **prompt/decision log** (3–5 lines total): one suggestion you kept + evidence, and one you rejected + why.\n\n---\n\n## Part 1: Getting set up (15 minutes)\n\n**Requirements**\n\n1. Install prerequisites\n\n- Python 3.10+\n- uv (package manager)\n\nInstall uv (macOS/Linux):\n\n```bash\ncurl -LsSf https://astral.sh/uv/install.sh | sh\n```\n\n2. Download the code\n\n```bash\ngit clone git@github.com:SamLau95/gmis-flask-reddit.git\ncd gmis-flask-reddit\n```\n\n3. Create the virtual environment and install dependencies\n\n```bash\nuv sync\n```\n\n4. Run the app\n\nRun using the Flask CLI:\n\n```bash\nuv run flask --app app run --debug\n```\n\nOpen `http://127.0.0.1:5000/` and confirm you see the dog links.\n\n---\n\n## Part 2: Add features (45 minutes)\n\nYou’ll add three features by mutating the `dog_links` variable. All actions\nshould update state on the server, then **redirect** back to `/` so the page\nrefreshes with the latest data.\n\n### Feature A: Upvotes and downvotes\n\n**Goal**: Users can upvote or downvote a link. After voting, the page reloads and items are always shown from highest score to lowest.\n\n**Behavior**\n\n- When the user clicks the up arrow or down arrow, the app should update that post’s `score` in `dog_links`.\n- After updating, redirect to the homepage.\n- On the homepage posts should always be ordered by `score` descending.\n\n### Feature B: Submit a new post\n\n**Goal**: Users can add a new post with `title` and `url`. New posts start with **1 upvote by default**.\n\n**Behavior**\n\n- Add a form to submit a new post.\n- Validate minimally: a non-empty `title` and a `url` that starts with `http` is fine.\n- Append to `dog_links` with `score = 1`.\n- Redirect back to `/`, then sort by `score` descending.\n\n**Acceptance tests**\n\n1. Submitting a valid post adds it to the list and displays score `1`.\n2. The post is placed relative to others based on its score (1).\n3. Empty title or invalid URL is rejected with a friendly message (no crash).\n\n### Feature C: Hide a post\n\n**Goal**: Users can hide any post. Hidden posts are not shown in the main list; instead they appear at the very bottom of the page under a section titled **“Hidden posts”**.\n\n**Behavior**\n\n- Add a \"Hide\" control for each post; toggling sets a simple flag on that item in `dog_links` (e.g., `hidden: True`).\n- The main feed shows only non-hidden posts, sorted by `score` descending.\n- At the bottom, render a separate section for **Hidden posts**.\n- Within Hidden posts, you may sort by score descending or leave original order—state your choice.\n\n**Acceptance tests**\n\n1. Hiding a post removes it from the main list immediately and places it under “Hidden posts.”\n2. Non-hidden posts remain sorted by `score` descending.\n3. Page reload after any action reflects the correct grouping and order.\n\n---\n\n## Part 3: Bug‑finding competition (25 minutes)\n\n1. **Swap projects** with another pair. Sit at their computer.\n2. **Find as many bugs as possible** (logic, UI, validation, sorting edge cases).\n3. **Document each bug** with steps, expected vs. actual, and a screenshot if helpful.\n4. **Share your findings** with the original team. Discuss overlaps and prevention ideas.\n\n---\n\n## Part 4: Feature request — persistence with SQLite (35 minutes)\n\nRight now `dog_links` resets on restart (e.g. if you stop the Flask app and restart it, the dog links will reset back to its original state). Add persistence with `sqlite3` so posts, votes, and hidden state survive restarts.\n\n**Goal**\n\n- On server start, load posts from a SQLite database.\n- When users vote/submit/hide, update the database.\n- On page load, query posts (grouped into visible/hidden), and render visible posts sorted by score descending.\n\n**Suggested schema (modify as you see fit)**\n\n- `posts(id INTEGER PRIMARY KEY, title TEXT NOT NULL, url TEXT NOT NULL, score INTEGER NOT NULL, hidden INTEGER NOT NULL DEFAULT 0, created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP)`\n\n**Behavior**\n\n- If the DB is empty on first run, **seed** it from the current `dog_links` contents.\n- Replace all in‑memory mutations with SQL `INSERT/UPDATE` and read fresh rows before rendering.\n- Preserve sorting by `score` descending for the main list; place hidden posts in the bottom section.\n\n**Acceptance tests**\n\n1. After voting/adding/hiding, restart the app; the state is preserved.\n2. New posts are stored with score `1` by default.\n3. Hidden state persists across restarts.\n4. Visible posts always appear sorted by `score` descending.\n\n---\n\n## LPDP: use the LLM as a thought companion (copy/paste)\n\n**Learner Context Card (paste/fill at the start):**\n\n```\nCourse \u0026 level:\nTask summary (1–2 lines): Build a server‑rendered Flask app for voting, posting, hiding.\nLanguage/stack: Python 3.10, Flask, sqlite3\nComfort (1–5): decomposition __ / syntax __ / debugging __ / testing __\nWhat I already tried:\nBiggest confusion:\nConstraints (perf/libs/style): no JS required; server‑side forms; readable code\nAllowed help: no full solutions; ≤8 lines/code nudge; prefer questions\nGoal for this session (120 min):\n```\n\n**Conversation contract (paste after the card):**\n\nBe my thought companion.\n\n1. Ask 3–5 diagnostic questions before ideas.\n2. Offer 2–3 options tied to MY constraints.\n3. No full code until I have checks; ≤8 lines if code is essential, explain line‑by‑line.\n4. After each step, ask for evidence (checks/outputs) before moving on.\n5. End each turn with: “Next two choices you could make are: …”\n\n**Short prompts to use during the build:**\n\n- **Clarify:** “Ask 4 questions to remove ambiguity in my vote/submit/hide routes and sorting rules.”\n- **Plan options:** “Suggest 2–3 ways to identify posts (index vs. id vs. composite key) and the trade‑offs.”\n- **Test‑first:** “Help me list 5 acceptance checks for voting, posting, hiding, and sorting.”\n- **Micro‑nudge:** “Give me ≤8 lines of pseudocode for POST‑redirect‑GET flow for voting.”\n- **Debug:** “Hiding then voting does something weird—ask 2 isolation questions and suggest 2 tiny probes.”\n- **Refactor:** “Offer 2 small refactors to reduce duplication across my vote/hide handlers.”\n- **Reflect:** “Interview me with 3 questions so I can explain one decision, one trade‑off, and one thing I’d test next.”\n\n---\n\n## Design clarifications\n\n- **Ordering rule:** Visible posts are sorted by `score` descending; ties can be broken arbitrarily.\n- **Hidden posts:** Render in a separate “Hidden posts” section at the bottom. They do not appear in the main list at the top of the homepage.\n- **Identifiers:** Choose a stable identifier for actions (array index is OK for Part 2; use `id` in Part 4).\n- **No JS needed:** Keep interactions as simple HTML forms.\n- **Validation:** Be kind to users—reject empty titles or clearly malformed URLs with a helpful message.\n- **Restart behavior:** In Part 2, state resets on restart. In Part 4, state must persist.\n\n---\n\n## Run (any time)\n\n```bash\nuv sync\nuv run flask --app app run --debug\n```\n\nOr:\n\n```bash\nuv run python app.py\n```\n\nOpen `http://127.0.0.1:5000/` to see the site.\n\n---\n\n## Optional stretch (only if time allows)\n\n- Unhide a post from the Hidden section.\n- Prevent negative scores or display them differently.\n- Add delete or edit for posts.\n- Add pagination if the list grows long.\n- Add simple unit tests for your sort/visibility logic.\n- CSS polish and accessibility checks (labels, focus order, contrast).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsamlau95%2Fgmis-flask-reddit","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsamlau95%2Fgmis-flask-reddit","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsamlau95%2Fgmis-flask-reddit/lists"}