Skip to content

Merge dev#7

Closed
dburcat wants to merge 95 commits intoZCW-Spring26:mainfrom
Circus-Circus-data-7-0:Merge_dev
Closed

Merge dev#7
dburcat wants to merge 95 commits intoZCW-Spring26:mainfrom
Circus-Circus-data-7-0:Merge_dev

Conversation

@dburcat
Copy link
Copy Markdown

@dburcat dburcat commented Apr 11, 2026

Merging into main new front end look and name change as well as delete post option and implemented user class.

NJIngram and others added 26 commits April 10, 2026 17:31
…r and recipient relationships established, blueprint
…tml updated to use her nav bar design, messages page style created to match what already exists, and style.css updated to address messing prompts.
Copilot AI review requested due to automatic review settings April 11, 2026 19:00
@dburcat dburcat closed this Apr 11, 2026
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR merges a broad set of “dev” changes into main, including a new UI/theme (“ZipChat”), a MySQL-based configuration path, and multiple new forum features (uploads/private posts, reactions, messages, admin subforum management) alongside significant refactoring of models/routes and expanded onboarding documentation.

Changes:

  • Reworked app startup/config (new run.sh, MySQL URI in config.py, schema-compat helper in forum/app.py).
  • Added/changed core features: file uploads + private posts + delete-post, reactions, and direct messages; plus admin-only create/delete subforums.
  • Large UI refresh across templates and CSS, plus new “how the project works” documentation.

Reviewed changes

Copilot reviewed 26 out of 31 changed files in this pull request and generated 19 comments.

Show a summary per file
File Description
run.sh New launcher that creates venv, installs deps, sets defaults, and runs Flask.
requirements.txt Adds dependencies for MySQL/crypto and HTTP client.
README.md Adds team guide + updated local startup instructions.
PROJECT_FLOW.md New high-level runtime/data-flow documentation.
MYSQL_MIGRATION_GUIDE.md New MySQL migration/startup guide.
CIRCUSCIRCUS_FULL_CODE_GUIDE.md New extensive onboarding/codebase guide.
Procfile Removed deployment entrypoint.
config.py Switches SQLAlchemy DB URI to MySQL + adds upload config values.
forum/init.py Registers new blueprints (posts/subforums/reactions/messages/auth).
forum/app.py Updates site metadata, seeds protected subforums, adds schema-compat logic.
forum/models.py Leaves shared db + helper validators; model classes moved to modules.
forum/routes.py Old monolithic routes are commented out; blueprint remains.
forum/user.py Introduces User model + auth blueprint + validation helpers.
forum/subforum.py Introduces Subforum model + subforum browse/create/delete endpoints.
forum/post.py Introduces Post model + uploads/private posts/comments/delete endpoints.
forum/Reactions.py Adds Reaction model + react endpoint.
forum/messages.py Adds Messages model + inbox/compose endpoints.
forum/templates/layout.html New layout shell + new external assets + JS include.
forum/templates/header.html New navbar + Messages link.
forum/templates/subforums.html New “hero” top-level subforums UI.
forum/templates/subforum.html Adds admin subforum actions + message links.
forum/templates/viewpost.html Adds private badge, uploads rendering, delete button, reactions, message links.
forum/templates/createpost.html Adds upload + “private post” option.
forum/templates/createsubforum.html New subforum creation page.
forum/templates/messages.html New messages UI.
forum/static/style.css Large ZipChat-themed CSS refresh + compatibility styles.
forum/static/js.txt Adds a small JS stub file.
forum/static/uploads/.gitkeep Keeps uploads directory tracked while ignoring user uploads.
.gitignore Ignores uploaded files under forum/static/uploads/*.
.DS_Store Adds macOS Finder metadata file to repo.
forum/.DS_Store Adds macOS Finder metadata file to repo under forum/.
Comments suppressed due to low confidence (1)

Procfile:1

  • Procfile was removed. If this app is deployed on a platform that relies on Procfile (e.g., Heroku), this will break the web process startup; either keep an updated Procfile (gunicorn entry) or update deployment docs/config accordingly.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread README.md

## Team Guide

If you want the full explanation of the MySQL migration, startup flow, and schema changes, read [MYSQL_MIGRATION_GUIDE.md](/Users/ethan/Projects/CircusCircus/MYSQL_MIGRATION_GUIDE.md).
Copy link

Copilot AI Apr 11, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

README links to MYSQL_MIGRATION_GUIDE.md using an absolute local filesystem path (/Users/...). This will be broken for everyone else and on GitHub; change it to a repository-relative link (e.g., ./MYSQL_MIGRATION_GUIDE.md).

Suggested change
If you want the full explanation of the MySQL migration, startup flow, and schema changes, read [MYSQL_MIGRATION_GUIDE.md](/Users/ethan/Projects/CircusCircus/MYSQL_MIGRATION_GUIDE.md).
If you want the full explanation of the MySQL migration, startup flow, and schema changes, read [MYSQL_MIGRATION_GUIDE.md](./MYSQL_MIGRATION_GUIDE.md).

Copilot uses AI. Check for mistakes.
Comment thread README.md
Comment on lines 49 to 56
```
$ python3.11 -m venv venv
$ source venv/bin/activate
$ pip install -r requirements.txt
$ ./run.sh
python3.11 -m venv venv
source venv/bin/activate
pip install -r requirements.txt
./run.sh
```

and it should appear on port 5000
Copy link

Copilot AI Apr 11, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

README’s quickstart implies a fixed port, but run.sh now defaults PORT to 8000 (and can be overridden via env). Update this section to reflect the new default and/or mention using $PORT.

Copilot uses AI. Check for mistakes.
Comment thread run.sh
Comment on lines +19 to +25
# MySQL-only configuration.
export DB_USER="${DB_USER:-zipchat_app}"
export DB_HOST="${DB_HOST:-127.0.0.1}"
export DB_PORT="${DB_PORT:-3306}"
export DB_NAME="${DB_NAME:-ZipChat}"
export DB_PASSWORD="${DB_PASSWORD:-password}"

Copy link

Copilot AI Apr 11, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

run.sh exports a hard-coded default DB_PASSWORD ("password"). Even if intended for local dev, this makes it easy to accidentally run with insecure credentials; consider requiring explicit DB_PASSWORD (or reading from a local .env) and/or printing a prominent warning when the default is used.

Copilot uses AI. Check for mistakes.
Comment thread config.py
Comment on lines +9 to +20
"""Configuration values consumed by Flask and Flask-SQLAlchemy."""

SECRET_KEY = environ.get("SECRET_KEY", "kristofer")
FLASK_APP = "forum.app"
UPLOAD_FOLDER = path.join(basedir, "forum", "static", "uploads")
ALLOWED_EXTENSIONS = {"png", "jpg", "jpeg", "gif", "mp4", "mov", "webm"}

DB_USER = environ.get("DB_USER", "zipchat_app")
DB_PASSWORD = environ.get("DB_PASSWORD", "password")
DB_HOST = environ.get("DB_HOST", "127.0.0.1")
DB_PORT = environ.get("DB_PORT", "3306")
DB_NAME = environ.get("DB_NAME", "ZipChat")
Copy link

Copilot AI Apr 11, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

config.py hard-codes insecure default credentials (SECRET_KEY="kristofer", DB_PASSWORD="password"). Defaults are convenient for local dev, but they are dangerous if deployed as-is; consider failing fast in non-dev environments or requiring these values to be set explicitly.

Copilot uses AI. Check for mistakes.
<link href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.css" rel="stylesheet">
<link rel="stylesheet" type="text/css" href="{{url_for('static', filename="bootstrap.min.css")}}">
<link rel="stylesheet" type="text/css" href="{{url_for('static', filename="style.css")}}">
<script src="{{url_for('static', filename="forum.js")}}"></script>
Copy link

Copilot AI Apr 11, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

layout.html includes a static asset "forum.js", but there is no corresponding file under forum/static/. This will 404 in the browser; either add forum/static/forum.js (or rename the existing js.txt) or remove the script tag.

Suggested change
<script src="{{url_for('static', filename="forum.js")}}"></script>

Copilot uses AI. Check for mistakes.
Comment thread MYSQL_MIGRATION_GUIDE.md
Comment on lines +65 to +76
### 4. Startup now tries to prepare MySQL automatically

`config.py` now includes startup helpers that:

- try to connect to MySQL as an admin user on the local machine
- create the `ZipChat` database if it is missing
- create the `zipchat_app` user if it is missing
- grant that user access to the database
- verify that the app credentials can connect

This is a best-effort bootstrap. If MySQL admin access is unavailable on a specific machine, the code prints clear instructions instead of failing silently.

Copy link

Copilot AI Apr 11, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

MYSQL_MIGRATION_GUIDE.md claims config.py performs MySQL admin bootstrap (create DB/user/grants), but the current config.py only builds SQLALCHEMY_DATABASE_URI and contains no such helpers. Either implement the described bootstrap logic or adjust the guide to match actual behavior so onboarding instructions are accurate.

Copilot uses AI. Check for mistakes.
Comment thread forum/static/js.txt
Comment on lines +1 to +7
function submitPost() {
const input = document.getElementById("composeInput");
if (!input.value.trim()) return;

alert("Post submitted: " + input.value);
input.value = "";
} No newline at end of file
Copy link

Copilot AI Apr 11, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

forum/static/js.txt is not a recognized asset name for browsers and is not referenced by any template (layout.html tries to load forum.js). Rename this to a .js file under static/ (and reference it), or remove it if it’s leftover.

Copilot uses AI. Check for mistakes.
Comment thread forum/app.py
Comment on lines +65 to +96
def ensure_model_schema_compatibility():
# Keep existing MySQL tables compatible with current and future model columns.
inspector = inspect(db.engine)
existing_tables = set(inspector.get_table_names())

with db.engine.begin() as conn:
for mapper in db.Model.registry.mappers:
table = mapper.local_table
table_name = table.name
if table_name not in existing_tables:
continue

existing_columns = {col["name"] for col in inspector.get_columns(table_name)}
for column in table.columns:
if column.name in existing_columns:
continue
if column.primary_key:
continue

column_type = column.type.compile(dialect=db.engine.dialect)
nullability = "NULL" if column.nullable else "NOT NULL"

default_sql = ""
if column.default is not None and getattr(column.default, "is_scalar", False):
default_sql = f" DEFAULT {_sql_literal(column.default.arg)}"

sql = (
f"ALTER TABLE `{table_name}` "
f"ADD COLUMN `{column.name}` {column_type} {nullability}{default_sql}"
)
conn.execute(text(sql))

Copy link

Copilot AI Apr 11, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ensure_model_schema_compatibility() runs ALTER TABLE statements automatically on app startup. This is operationally risky (startup DDL, potential locks, partial schema updates, missing indexes/constraints, and races with concurrent app instances). Prefer using a proper migration tool (Alembic/Flask-Migrate) and keeping startup read-only with respect to schema.

Copilot uses AI. Check for mistakes.
Comment thread forum/post.py
Comment on lines +94 to +102
@post_rt.route('/action_comment', methods=['POST', 'GET'])
@login_required
def comment():
post_id = int(request.args.get("post"))
post = Post.query.filter(Post.id == post_id).first()
if not post:
return error("That post does not exist!")
content = request.form['content']
reply = Post(content=content, postdate=datetime.datetime.now())
Copy link

Copilot AI Apr 11, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

action_comment declares methods=['POST','GET'] but the handler unconditionally reads request.form['content'], which will fail on GET. Restrict this endpoint to POST only (or handle GET explicitly).

Copilot uses AI. Check for mistakes.
Comment thread forum/post.py
Comment on lines +143 to +155
@post_rt.route('/action_delete_post', methods=['POST'])
@login_required
def action_delete_post():
post_id = int(request.form['post_id'])
post = Post.query.filter(Post.id == post_id).first()
if not post:
return error("That post does not exist!")
if post.user_id != current_user.id and not current_user.admin:
return error("You do not have permission to delete this post.")
Post.query.filter(Post.parent_id == post_id).delete()
db.session.delete(post)
db.session.commit()
return redirect("/subforum?sub=" + str(post.subforum_id)) No newline at end of file
Copy link

Copilot AI Apr 11, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These POST endpoints (delete post, react, send message, delete subforum) are vulnerable to CSRF because the app does not include CSRF tokens in forms or server-side CSRF validation. Consider adding CSRF protection (e.g., Flask-WTF or a custom token) at least for state-changing/destructive actions.

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants