That way, we may have multiple comments on a report.
Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
-- PostgreSQL database dump
--
-\restrict ZeEQIdrFtt8lZBacF2YikE2NldALCViC5aH05xXVTjf5DSP1ITtfKT3w9cYoumo
+\restrict 97QQcysG1ebcqz7Y7sN4EJb44D05KafpruWuQjJfkHpdoO21URCTKpqX39K4fwP
-- Dumped from database version 17.7 (Debian 17.7-0+deb13u1)
-- Dumped by pg_dump version 17.7 (Debian 17.7-0+deb13u1)
ALTER SEQUENCE public.nameservers_id_seq OWNED BY public.nameservers.id;
+--
+-- Name: report_comments; Type: TABLE; Schema: public; Owner: -
+--
+
+CREATE TABLE public.report_comments (
+ id uuid DEFAULT gen_random_uuid() NOT NULL,
+ report_id uuid NOT NULL,
+ created_at timestamp with time zone DEFAULT CURRENT_TIMESTAMP NOT NULL,
+ created_by text,
+ deleted_at timestamp with time zone,
+ deleted_by text,
+ comment text DEFAULT ''::text NOT NULL,
+ points integer DEFAULT 0 NOT NULL
+);
+
+
--
-- Name: reports; Type: TABLE; Schema: public; Owner: -
--
reported_by text NOT NULL,
closed_at timestamp with time zone,
closed_by text,
- comment text DEFAULT ''::text NOT NULL,
block boolean DEFAULT true,
accepted boolean DEFAULT false
);
ADD CONSTRAINT nameservers_pkey PRIMARY KEY (id);
+--
+-- Name: report_comments report_comments_pkey; Type: CONSTRAINT; Schema: public; Owner: -
+--
+
+ALTER TABLE ONLY public.report_comments
+ ADD CONSTRAINT report_comments_pkey PRIMARY KEY (id);
+
+
--
-- Name: reports reports_pkey; Type: CONSTRAINT; Schema: public; Owner: -
--
CREATE UNIQUE INDEX lists_unique ON public.lists USING btree (slug) WHERE (deleted_at IS NULL);
+--
+-- Name: report_comments_report_id; Type: INDEX; Schema: public; Owner: -
+--
+
+CREATE INDEX report_comments_report_id ON public.report_comments USING btree (report_id) WHERE (deleted_at IS NULL);
+
+
--
-- Name: reports_open; Type: INDEX; Schema: public; Owner: -
--
ADD CONSTRAINT list_stats_list_id FOREIGN KEY (list_id) REFERENCES public.lists(id);
+--
+-- Name: report_comments report_comments_report_id; Type: FK CONSTRAINT; Schema: public; Owner: -
+--
+
+ALTER TABLE ONLY public.report_comments
+ ADD CONSTRAINT report_comments_report_id FOREIGN KEY (report_id) REFERENCES public.reports(id);
+
+
--
-- Name: reports reports_list_id; Type: FK CONSTRAINT; Schema: public; Owner: -
--
-- PostgreSQL database dump complete
--
-\unrestrict ZeEQIdrFtt8lZBacF2YikE2NldALCViC5aH05xXVTjf5DSP1ITtfKT3w9cYoumo
+\unrestrict 97QQcysG1ebcqz7Y7sN4EJb44D05KafpruWuQjJfkHpdoO21URCTKpqX39K4fwP
# Send 204
return fastapi.Response(status_code=fastapi.status.HTTP_204_NO_CONTENT)
+"""
+ Comments
+"""
+
+@router.get("/{id}/comments")
+async def get_comments(
+ report: reports.Report = fastapi.Depends(get_report_from_path)
+) -> list[reports.ReportComment]:
+ return [comment async for comment in report.get_comments()]
+
# Include our endpoints
app.include_router(router)
return await self.backend.db.fetch_one(stmt)
- async def create(self, **kwargs):
+ async def create(self, comment=None, **kwargs):
"""
Creates a new report
"""
# Manifest the object in the database immediately to assign the ID
await self.backend.db.flush_and_refresh(report)
+ # Post the comment
+ if comment:
+ await report.comment(
+ comment=comment, reporter=report.reported_by, notify=False,
+ )
+
# Increment the counter of the list
report.list.pending_reports += 1
# Closed By
closed_by : str | None
- # Comment
- comment : str = ""
-
# Block?
block : bool = True
@property
def url(self):
return "https://www.ipfire.org/dbl/reports/%s" % self.id
+
+ # Comments
+
+ def get_comments(self):
+ """
+ Returns all (non-deleted) comments to this report
+ """
+ return self.backend.db.fetch(
+ sqlmodel
+ .select(
+ ReportComment,
+ )
+ .where(
+ # Must match the report
+ ReportComment.report == self,
+
+ # Must not be deleted
+ ReportComment.deleted_at == None,
+ )
+ .order_by(
+ ReportComment.created_at,
+ )
+ )
+
+ async def comment(self, comment, reporter, points=0, notify=True):
+ """
+ Posts a new comment to this report
+ """
+ # Write the comment to the database
+ comment = await self.backend.db.insert(
+ ReportComment,
+ report = self,
+ created_by = reporter,
+ comment = comment,
+ points = points,
+ )
+
+ # Send a notification about this comment
+ if notify:
+ pass # XXX TODO
+
+ return comment
+
+
+class ReportComment(sqlmodel.SQLModel, database.BackendMixin, table=True):
+ __tablename__ = "report_comments"
+
+ def __str__(self):
+ return "%s" % self.id
+
+ def __eq__(self, other):
+ if isinstance(other, self.__class__):
+ return self.id == other.id
+
+ return NotImplemented
+
+ def __lt__(self, other):
+ if isinstance(other, self.__class__):
+ return (self.report, self.created_at) < (other.report, other.created_at)
+
+ return NotImplemented
+
+ # ID
+ id: uuid.UUID = sqlmodel.Field(
+ primary_key=True, default=sqlmodel.func.gen_random_uuid(),
+ )
+
+ # Report ID
+ report_id: uuid.UUID = sqlmodel.Field(foreign_key="reports.id", exclude=True)
+
+ # report
+ report: "Report" = sqlmodel.Relationship(
+ sa_relationship_kwargs = {
+ "lazy" : "joined",
+ "innerjoin" : True,
+ },
+ )
+
+ # Created At
+ created_at: datetime.datetime = sqlmodel.Field(
+ sa_column_kwargs = {"server_default" : sqlmodel.text("CURRENT_TIMESTAMP")}
+ )
+
+ # Created By
+ created_by: str
+
+ # Deleted At
+ deleted_at: datetime.datetime | None = sqlmodel.Field(exclude=True)
+
+ # Deleted By
+ deleted_by: str | None = sqlmodel.Field(exclude=True)
+
+ # Comment
+ comment: str = ""
+
+ # Points
+ points: int = 0