-
Notifications
You must be signed in to change notification settings - Fork 30
Feature/contact us backend : backend apis implemented for contact us form along with admin management page. #106
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 077defd434
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
backend-api/app/main.py
Outdated
| @app.on_event("startup") | ||
| async def init_contact_schema() -> None: | ||
| async with engine.begin() as conn: | ||
| await conn.run_sync(Base.metadata.create_all) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Avoid runtime DDL on every app startup
This startup hook runs Base.metadata.create_all for every process start, which executes DDL for all models. In environments where the API role is DML‑only (common when migrations are applied out‑of‑band), this will raise a permission error and prevent the service from starting, and the contact tables will never be created because no migration is included in this commit. Consider shipping an Alembic migration for the contact tables and removing (or gating) the runtime create_all to dev‑only scenarios.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is addressed in new commit
|
@codex review |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 2c0aaea622
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
backend-api/app/api/v1/contact.py
Outdated
| if "status" in payload.__fields_set__: | ||
| track_change("status", submission.status, payload.status) | ||
| submission.status = payload.status | ||
| if payload.status and payload.status.lower() == "resolved" and payload.resolved_at is None: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reject null status/priority updates
Because ContactSubmissionUpdate allows status/priority to be null, this code assigns the payload directly when the field is present. If a client sends { "status": null } (or { "priority": null } in the block just below), SQLAlchemy will try to persist NULL into columns that are nullable=False in backend-api/alembic/versions/j1k2l3m4n567_add_contact_us_tables.py, which will raise an integrity error and return a 500 instead of a 4xx. Consider validating non-null values when these fields are provided or ignoring explicit nulls.
Useful? React with 👍 / 👎.
…y updates review addressed
|
@codex review |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: a6cc080170
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
|
@codex review |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: d94511ed9e
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
|
@codex review |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: bd37874ac2
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
|
@codex review |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 244fcd6595
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| if (currentId !== selectedId) { | ||
| return; | ||
| } | ||
| setNotes(noteData); | ||
| setHistory(historyData); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Prevent stale detail updates from earlier requests
When admins click between submissions quickly, this guard won’t actually prevent the older request from overwriting notes/history for the newly selected submission. In this effect, currentId is assigned from selectedId in the same render, so currentId !== selectedId will never be true, and a slower response can still update state for the wrong submission. This shows up as notes/history mismatching the selected item; using a ref/abort controller or comparing against the latest selection would avoid stale updates.
Useful? React with 👍 / 👎.
|
@codex review |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: c5363070c1
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
backend-api/app/api/v1/contact.py
Outdated
| if "status" in payload.__fields_set__: | ||
| if payload.status is None: | ||
| raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail="status cannot be null") | ||
| track_change("status", submission.status, payload.status) | ||
| submission.status = payload.status | ||
| if payload.status.lower() == "resolved" and submission.resolved_at is None: | ||
| submission.resolved_at = datetime.utcnow() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Update resolved_at when re-resolving submissions
When the status is changed to resolved, resolved_at is only set if it is currently None. If a submission is reopened (status moved to in_progress/closed) and later resolved again, the timestamp stays at the original value, so reports/SLA metrics will show an outdated resolution time. This only happens after a submission is resolved once and later re-resolved. Consider resetting resolved_at when status moves away from resolved and/or always updating it when status becomes resolved.
Useful? React with 👍 / 👎.
|
@codex review |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: fcfd0a7569
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
backend-api/app/api/v1/contact.py
Outdated
| if "status" in payload.__fields_set__: | ||
| if payload.status is None: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Replace deprecated fields_set with v2 API
With pydantic>=2.11.7 (see backend-api/pyproject.toml), BaseModel no longer exposes __fields_set__; the correct accessor is model_fields_set (or use payload.model_dump(exclude_unset=True) to drive updates). As written, this line will raise AttributeError on any PATCH request, causing /v1/contact/submissions/{id} to 500 instead of applying updates. This only manifests when the update endpoint is called under the Pydantic v2 runtime.
Useful? React with 👍 / 👎.
|
@codex review |
|
Codex Review: Didn't find any major issues. Delightful! ℹ️ About Codex in GitHubCodex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback". |
romil-bijarnia
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hey Nikhil, Thanks for pushing these changes. The backend changes look all good to me and it is nice to have this functionality intact, would you please be able to make some changes in terms of the UI aspect of things. I feel the ContactAdminPage.jsx can be designed better, I have highlighted some inconsitencies I stopped in the screenshot you added :

I'd appreciate if you could address the ui changes and then upload another screenshot.
|
@codex review |
|
Codex Review: Didn't find any major issues. Keep them coming! ℹ️ About Codex in GitHubCodex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback". |
|
Hello @nikhil-3210 , these changes look alright. Could you remove the refresh icon for me as we may not need that. Also there are a lot of emojis used in the UI, we should refrain from using them and should keep using symbols like we have for the rest of the website |
|
@codex review |
|
Codex Review: Didn't find any major issues. Chef's kiss. ℹ️ About Codex in GitHubCodex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback". |
|
Hi @nikhil-3210 — requesting changes before merge. I reviewed the PR code + tested the UI.
After fixes, please re-test end-to-end and attach screenshots/GIFs showing:
|
|
@nikhil-3210 How are the requested changes progressing? Any issues? |
|
@du-dhartley, working on requested changes. it should be done by tomorrow evening. |
|
Hey @nikhil-3210 — I checked the PR. On the admin page (frontend/src/pages/Admin/ContactAdminPage.jsx), the Status and Priority controls are implemented as native HTML select elements.
Because of that, the opened dropdown menu is rendered by the browser/OS (not fully by our CSS/theme). On some setups (e.g., Chrome/macOS), it shows up as a white popup even if the closed control is styled dark. So there won’t be a console “error”, and you might not reproduce it depending on your browser/OS/theme settings.
I'd appreciate it if you could use the existing pattern for the select components being used in the ui. Please refer to the evidence scanner page and you can see the current styling for the dropdown:
I believe this is the styling class: (In Evidence.css) |
|
@codex review |
|
Codex Review: Didn't find any major issues. Another round soon, please! ℹ️ About Codex in GitHubCodex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback". |
|
Hi @romil-bijarnia — thanks for the detailed review. I’ve addressed all the requested changes: Contact form: Disabled native HTML validation (noValidate) and implemented inline validation using the existing error state (no yellow browser tooltips now).
Select dropdowns: Updated Subject (Contact form) and Status/Priority (Admin page) to use the existing themed select pattern so the dropdown matches the dark theme (tested on Chrome/macOS).
Admin success banner: actionMessage now auto-clears after 5 seconds (and I also clear old errors on successful actions so they don’t linger).
after 5 sec
|
romil-bijarnia
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for addressing the feedback
















Overview
The Contact Us feature provides a public submission endpoint and an admin-only management workflow.
It stores submissions, notes and history in the database and exposes CRUD APIs for admins.
Admin authorization is enforced using the existing
usertable andadminrole.Admin Page (Frontend)
http://localhost:3000/admin/contact-submissionsAPI Endpoints (Base:
/v1)Total endpoints: 8
Public:
POST /contact— Create a new Contact Us submission.Admin-only (requires
adminrole):GET /contact/submissions— List all submissions.GET /contact/submissions/{submission_id}— Get a single submission by ID.PATCH /contact/submissions/{submission_id}— Update status/priority/assignment/resolved_at.DELETE /contact/submissions/{submission_id}— Delete a submission.GET /contact/submissions/{submission_id}/notes— List notes for a submission.POST /contact/submissions/{submission_id}/notes— Add a note (internal or external).GET /contact/submissions/{submission_id}/history— List audit history for a submission.Tables:
contact_submissionsid(UUID, PK)first_name,last_name,email(required)phone,company,source,ip_address(optional)subject,message(required)status(default:new)priority(default:medium)assigned_to(FK →user.id)created_at,updated_at,resolved_atsubmission_notesid(UUID, PK)submission_id(FK →contact_submissions.id)admin_user_id(FK →user.id)noteis_internal(default:true)created_at,updated_atsubmission_historyid(UUID, PK)submission_id(FK →contact_submissions.id)admin_user_id(FK →user.id)action,field_name,old_value,new_valuecreated_atStartup Behavior
On app startup, table creation is triggered with
Base.metadata.create_allto ensure the Contact Us tables exist.contact us public page

contact us database entried

admin only page.
