Commit Graph

458 Commits

Author SHA1 Message Date
Klaas van Schelven
e60fbb2cd5 Fix invalid focus:ring-3-* classnames from migration
Tailwind 3 -> 4 migration renamed `ring` -> `ring-3`, but colors like
`ring-cyan-200` were also changed to `ring-3-cyan-200` which doesn't
actually exist.

broken in ac8e2e8cd6

See #225 (the present commit is related, but not a full fix)
2025-09-22 09:50:35 +02:00
Klaas van Schelven
4d3756f621 API: leave notes on get_object's future 2025-09-18 20:12:28 +02:00
Klaas van Schelven
1611ea45d2 Merge pull request #211 from bugsink/canonical-api
"Canonincal" (Bugsink-specific) API: first version
2025-09-15 16:41:25 +02:00
Klaas van Schelven
4d18008cd8 Bandit fixes
also brings the exception-handling of apply_sourcemaps inline
w/ issues/views.py (as promised per the module header)
2025-09-15 16:29:06 +02:00
Klaas van Schelven
d3fd513e43 Remove 'last' handling of exceptions md
you generally just want the whole stacktrace, I'd say
2025-09-15 16:24:59 +02:00
Klaas van Schelven
17007d5f55 MarkDown: in the regular UI too
See #127
2025-09-15 15:28:07 +02:00
Klaas van Schelven
bfcbf8005a Note/comment about CursorPagination vs other approaches 2025-09-12 17:28:10 +02:00
Klaas van Schelven
0fb81b29ae markdown_stacktrace util: display an event's stacktrace in markdown 2025-09-12 16:41:39 +02:00
Klaas van Schelven
a4e84fa0a3 Add Swagger using drf-spectacular
See #146

DRF 3.16 and Django 5.2 are not in drf-spectacular's published
list of supported but here's some sources that give reason to believe
they are supported _in practice_:

* https://github.com/tfranzel/drf-spectacular/issues/1417
* https://github.com/tfranzel/drf-spectacular/issues/1414
2025-09-12 11:46:44 +02:00
Klaas van Schelven
9ad66d7b50 API: adhere to Bugsink's DB-transactional model
as per https://www.bugsink.com/blog/database-transactions/
2025-09-11 18:01:05 +02:00
Klaas van Schelven
07b792775a API pagination 2025-09-11 16:52:14 +02:00
Klaas van Schelven
ee5b49e951 API: Sketch TODO for grouping_key[s] fields
See #146
2025-09-11 09:55:21 +02:00
Klaas van Schelven
829cea1a80 detection of a new release through an event ⇏ triggering of a TurningPoint
This more exactly expresses semantics by itself, and is also in preparation of
creating releases through the API (which have no triggering event)

See #146
2025-09-11 09:55:09 +02:00
Klaas van Schelven
3bab02fda2 API: Remove global Grouping routes
grouping will return later as Issue.grouping_keys & Event.grouping_key
i.e. with the relevant info directly resolved

See #146
2025-09-11 09:55:01 +02:00
Klaas van Schelven
c4c749d1e4 Issues API
See #146
2025-09-11 09:54:51 +02:00
Klaas van Schelven
63c54b2107 Comment about is_deleted & indexes 2025-09-10 09:02:44 +02:00
Klaas van Schelven
1262719e4b Comments about (SDK-generated) event_id's uniqueness
'original sin' in 238fb6dda7
2025-09-09 21:13:54 +02:00
Klaas van Schelven
4c2c26743e Canonical API 'skeleton': urls & views
this gives me something to look at and work with, despite
being wildly incomplete

See #146
2025-09-09 10:07:10 +02:00
Klaas van Schelven
a4ecd386b6 Support hosting at subpath
"In principle" setting `SCRIPT_NAME` is enough. The way we do this is [1] using
`FORCE_SCRIPT_NAME` (which does not depend on messing with reverse proxy
settings and [2] by deducing the correct value from `BASE_URL` (which must be
set anyway) automatically.

By works I mean: `reverse` and `{% url` pick it up from there.

However, there are subtleties / extra work:

* `STATIC_URL` is needed too b/c https://code.djangoproject.com/ticket/34028

* in many pre-existing code I just created a path manually in the html. Such
  hrefs are obviously not magically fixed for script_name. Rather than doing
  the "full rewrite" (into `{% url`) this commit just prepends the
  `script_name` in those cases. That's the way forward that will least likely
  break and it gives us something to grep for if we ever want to 'do it
  right'.

* `LOGIN_REDIRECT_URL` and `LOGIN_URL` needed to use a view-name for this to
  work (using a view-name gets revolved using the thing that introduces
  `script_name`)

Checked, no work needed:

* views (`redirect` and `HttpResponseRedirect`)
* html uses of action="..."

Fix #93
2025-09-05 22:47:22 +02:00
Klaas van Schelven
ad8a2a5e4f Tailwind 3 => 4: bg-opacity "folded into bg"
https://tailwindcss.com/docs/upgrade-guide#renamed-utilities
2025-09-04 13:20:22 +02:00
Klaas van Schelven
610e7b1c17 Tailwind 3 => 4: rounded => rounded-sm
https://tailwindcss.com/docs/upgrade-guide#renamed-utilities
2025-09-04 13:20:22 +02:00
Klaas van Schelven
ac8e2e8cd6 Tailwind 3 => 4: ring => ring-3
https://tailwindcss.com/docs/upgrade-guide#renamed-utilities
2025-09-04 13:20:22 +02:00
某亚瑟
2b5fb1bf67 Basically completed i18n support, and Chinese translation
Implement most Chinese text translations, adding default recognition browser language and user settings language
2025-08-02 10:25:19 +08:00
Klaas van Schelven
354af7ea0a Fix issues as reported by bandit or mark as nosec
Nothing worrying, but good to have checked this regardless
and important to have a green pipeline.

Fix #175
2025-07-30 12:16:40 +02:00
Klaas van Schelven
9b8409d8b2 Global trailing whitespace cleanup 2025-07-29 12:53:10 +02:00
Klaas van Schelven
ceca12940b Breadcrumb timestamps: display harmonized w/ rest of application
in the correct timezone, with smaller milis

According to the spec, this should work because:

> The timestamp of the breadcrumb. Recommended. A timestamp representing when
> the breadcrumb occurred. The format is either a string as defined in [RFC
> 3339](https://tools.ietf.org/html/rfc3339) or a numeric (integer or float)
> value representing the number of seconds that have elapsed since the [Unix
> epoch](https://en.wikipedia.org/wiki/Unix_time). Breadcrumbs are most useful
> when they include a timestamp, as it creates a timeline leading up to an
> event.
2025-07-28 10:24:48 +02:00
Klaas van Schelven
6b8d912e1a Store remote_addr on the event
Fix #165
2025-07-25 21:54:32 +02:00
Klaas van Schelven
c4fe1c1292 Debug IDs for missing sourcemaps: show them right in the stacktrace
See #158
2025-07-23 10:57:30 +02:00
Klaas van Schelven
1983633b38 Sourcemap Images IDs: show those in event_details
See #158
2025-07-23 10:38:45 +02:00
Klaas van Schelven
fd80eff7ca Migration fix: delete TurningPoints w/ project=None
Fix #155
2025-07-17 14:41:27 +02:00
Klaas van Schelven
45ad2aceec Dark mode: use monokai style from pygments
Fix #152
2025-07-17 09:45:22 +02:00
Klaas van Schelven
421ac91dc5 Fix overflow issue when function-names are very long
As per the "little red box on" #120
2025-07-15 10:35:16 +02:00
Klaas van Schelven
ae2bc56c04 Text-overflow for issue pages (date and '1 of 1 total')
> that "10 july ... event 1 of 1 total" should get overflow properties just like the exception.type below it.

See #120
2025-07-15 10:23:55 +02:00
Klaas van Schelven
89accddc2f Fix wasted space at certain width in stacktrace UI
* The "collapse" etc. buttons get shown below the search box and < << >> > from
  a certain width downwards.

* similar stacking for the date/type/value and the buttons at an even smaller width.

See #120
2025-07-15 09:41:35 +02:00
Klaas van Schelven
f21d9f989b Fix recently added UI elements to have dark mode too
the elements were added after the work on #125 was done but in a
branch w/o dark-mode, so they needed to still be fixed
2025-07-07 11:39:27 +02:00
Klaas van Schelven
d99f946665 Merge branch 'main' into feature/add_dark_theme 2025-07-07 11:08:00 +02:00
Klaas van Schelven
7b340fd8ff Hide in-progress deletions of Project & Issue from the UI
I've done a full grep on Issue.objects, Project.objects and get_object_or_404
equivelents, and applying some common sense. The goal: avoid having
confusing/half-broken pages in the UI.

On index-usage: I've decided not to update the indexes. The assumption is:
`is_deleted` items will be a tiny minority of items in general, making the
cost/benefit analysis not turn out favorably (just scanning them out as a final
step is more efficient).  Also: sqlite is able to use the correct index without
adding a special one, proof:

```
EXPLAIN QUERY PLAN SELECT [..] WHERE ("issues_issue"."project_id" = 1 AND "issues_issue"."is_muted" = (0) AND "issues_issue"."is_resolved" = (0)) ORDER BY "issues_issue"."last_seen" DESC LIMIT 250;
QUERY PLAN
`--SEARCH issues_issue USING INDEX issue_list_open (project_id=? AND is_resolved=? AND is_muted=?)

EXPLAIN QUERY PLAN SELECT [..] WHERE ("issues_issue"."project_id" = 1 AND "issues_issue"."is_muted" = (0) AND "issues_issue"."is_resolved" = (0) AND "issues_issue"."is_deleted" = 0) ORDER BY "issues_issue"."last_seen" DESC LIMIT 250;
QUERY PLAN
`--SEARCH issues_issue USING INDEX issue_list_open (project_id=? AND is_resolved=? AND is_muted=?)
```

See #139 for the 0/1 notation in the above.

(Project-indexes: not an issue, the scale is "below relevance for indexes")
2025-07-07 10:27:36 +02:00
Klaas van Schelven
308034aadd Issue-delete from the UI (in the list-view)
See #50
2025-07-04 21:25:57 +02:00
Klaas van Schelven
3e2bc290fd Fix typo in 'breadcrumbs' first/last urls.py 2025-07-04 17:33:02 +02:00
Klaas van Schelven
4900f0447e Project-deletion: slight optimization
Removes the following 2 redundant queries from the deletion process:

```
SELECT "tags_tagkey"."id" FROM "tags_tagkey" WHERE "tags_tagkey"."project_id" IN (1) ORDER BY "tags_tagkey"."project_id" ASC, "tags_tagkey"."id" ASC LIMIT 498
UPDATE "projects_project" SET "stored_event_count" = ("projects_project"."stored_event_count" - 1) WHERE "projects_project"."id" = 1
```
2025-07-03 22:04:51 +02:00
Klaas van Schelven
28b2ce0eaf Various models: .project SET_NULL => DO_NOTHING
Like e45c61d6f0, but for .project.

I originally thought `SET_NULL` would be a good way to "do stuff later", but
that's only so the degree that [1] updates are cheaper than deletes and [2]
2nd-order effects (further deletes in the dep-tree) are avoided.

Now that we have explicit Project-deletion (deps-first, delayed, properly batched)
the SET_NULL behavior is always a no-op (but with cost in queries).

As a result, in the test for project deletion (which has deletes for many
of the altered models), the following 12 queries are no longer done:

```
SELECT "projects_project"."id", [..many fields..] FROM "projects_project" WHERE "projects_project"."id" = 1
DELETE FROM "projects_projectmembership" WHERE "projects_projectmembership"."project_id" IN (1)
DELETE FROM "alerts_messagingserviceconfig" WHERE "alerts_messagingserviceconfig"."project_id" IN (1)
UPDATE "releases_release" SET "project_id" = NULL WHERE "releases_release"."project_id" IN (1)
UPDATE "issues_issue" SET "project_id" = NULL WHERE "issues_issue"."project_id" IN (1)
UPDATE "issues_grouping" SET "project_id" = NULL WHERE "issues_grouping"."project_id" IN (1)
UPDATE "events_event" SET "project_id" = NULL WHERE "events_event"."project_id" IN (1)
UPDATE "tags_tagkey" SET "project_id" = NULL WHERE "tags_tagkey"."project_id" IN (1)
UPDATE "tags_tagvalue" SET "project_id" = NULL WHERE "tags_tagvalue"."project_id" IN (1)
UPDATE "tags_eventtag" SET "project_id" = NULL WHERE "tags_eventtag"."project_id" IN (1)
UPDATE "tags_issuetag" SET "project_id" = NULL WHERE "tags_issuetag"."project_id" IN (1)
```
2025-07-03 21:49:49 +02:00
Klaas van Schelven
6b9e4d8011 Project.delete_deferred(): first version (WIP)
Implemented using a batch-wise dependency-scanner in delayed
(snappea) style.

* no real point-of-entry in the (regular, non-admin) UI yet.
* no hiding of Projects which are delete-in-progress from the UI

* lack of DRY
* some unnessary work (needed in the Issue-context, but not here)
  is still being done.

See #50
2025-07-03 21:01:28 +02:00
Klaas van Schelven
99f71b8a47 Fix the tests (query-counting across DBs) 2025-07-03 14:48:51 +02:00
Klaas van Schelven
eb5e2d2a48 Fix 'delay_on_commit' calls for project-id passing-around 2025-07-03 13:46:40 +02:00
Klaas van Schelven
6a75216c8f Document issue-deletion batch size budget 2025-07-03 13:46:16 +02:00
Klaas van Schelven
2baa4446fd Issue deletion: event pre-deletes (storage, project-counts) 2025-07-03 13:18:28 +02:00
Klaas van Schelven
3b3ce782c5 Fix the tests for prev. commit
tests were broken b/c not respecting constraints / not properly using the factories.
2025-07-03 11:33:58 +02:00
Klaas van Schelven
e45c61d6f0 Various models: .issue and .grouping; SET_NULL => DO_NOTHING
I originally thought `SET_NULL` would be a good way to "do stuff later", but
that's only so the degree that [1] updates are cheaper than deletes and [2]
2nd-order effects (further deletes in the dep-tree) are avoided.

Now that we have explicit Issue-deletion (deps-first, delayed, properly batched)
the SET_NULL behavior is always a no-op (but with cost in queries).

As a result, in the test for issue deletion (which has deletes for many
of the altered models), the following 8 queries are no longer done:

```
SELECT "issues_grouping"."id", [..many fields..] FROM "issues_grouping" WHERE "issues_grouping"."id" IN (1)
UPDATE "events_event" SET "grouping_id" = NULL WHERE "events_event"."grouping_id" IN (1)

[.. a few moments later..]

SELECT "issues_issue"."id", [..many fields..] FROM "issues_issue" WHERE "issues_issue"."id" = 'uuid'
UPDATE "issues_grouping" SET "issue_id" = NULL WHERE "issues_grouping"."issue_id" IN ('uuid')
UPDATE "issues_turningpoint" SET "issue_id" = NULL WHERE "issues_turningpoint"."issue_id" IN ('uuid')
UPDATE "events_event" SET "issue_id" = NULL WHERE "events_event"."issue_id" IN ('uuid')
UPDATE "tags_eventtag" SET "issue_id" = NULL WHERE "tags_eventtag"."issue_id" IN ('uuid')
UPDATE "tags_issuetag" SET "issue_id" = NULL WHERE "tags_issuetag"."issue_id" IN ('uuid')
```

(breaks the tests b/c of constraints and not always using factories; will fix next)
2025-07-03 11:33:58 +02:00
Klaas van Schelven
e58be0018f Tag models: no CASCADE
CASCADE was defined for keys & values, but in practice those are never directly
deleted except in the very case in which it has been established that they are
'orphaned', i.e. no longer being referrred to. That's exactly the case in which
CASCADE is superfluous.

As a result, in the test for issue deletion (which contains a prune of
tagvalue), the following 3 queries are no longer done:

```
SELECT "tags_tagvalue"."id", "tags_tagvalue"."project_id", "tags_tagvalue"."key_id", "tags_tagvalue"."value" FROM "tags_tagvalue" WHERE "tags_tagvalue"."id" IN (1)
DELETE FROM "tags_eventtag" WHERE "tags_eventtag"."value_id" IN (1)
DELETE FROM "tags_issuetag" WHERE "tags_issuetag"."value_id" IN (1)
```
2025-07-03 11:33:58 +02:00
Klaas van Schelven
428011ff9b Prune orphans (TagValue, via IssueTag) inline
See #135
2025-07-03 11:33:53 +02:00