Exosphere is a set of small, modular, self-hostable community tools built on the AT Protocol. app.exosphere.site
7
fork

Configure Feed

Select the types of activity you want to include in your feed.

fix: remove created at in db schema

Hugo b7d16c90 a156f40f

+862 -44
+6
drizzle/0001_hard_vulture.sql
··· 1 + DROP INDEX `idx_feature_requests_created`;--> statement-breakpoint 2 + ALTER TABLE `feature_requests` DROP COLUMN `created_at`;--> statement-breakpoint 3 + DROP INDEX `idx_feed_posts_created`;--> statement-breakpoint 4 + ALTER TABLE `feed_posts` DROP COLUMN `created_at`;--> statement-breakpoint 5 + ALTER TABLE `feature_request_comments` DROP COLUMN `created_at`;--> statement-breakpoint 6 + ALTER TABLE `feature_request_statuses` DROP COLUMN `created_at`;
+813
drizzle/meta/0001_snapshot.json
··· 1 + { 2 + "version": "6", 3 + "dialect": "sqlite", 4 + "id": "f4f4db59-eefb-4ebd-93d1-0b85cc219fe4", 5 + "prevId": "7333f8c4-b6fc-4b06-baf1-b769e893cb37", 6 + "tables": { 7 + "oauth_sessions": { 8 + "name": "oauth_sessions", 9 + "columns": { 10 + "key": { 11 + "name": "key", 12 + "type": "text", 13 + "primaryKey": true, 14 + "notNull": true, 15 + "autoincrement": false 16 + }, 17 + "session": { 18 + "name": "session", 19 + "type": "text", 20 + "primaryKey": false, 21 + "notNull": true, 22 + "autoincrement": false 23 + }, 24 + "created_at": { 25 + "name": "created_at", 26 + "type": "text", 27 + "primaryKey": false, 28 + "notNull": true, 29 + "autoincrement": false, 30 + "default": "(datetime('now'))" 31 + }, 32 + "updated_at": { 33 + "name": "updated_at", 34 + "type": "text", 35 + "primaryKey": false, 36 + "notNull": true, 37 + "autoincrement": false, 38 + "default": "(datetime('now'))" 39 + } 40 + }, 41 + "indexes": {}, 42 + "foreignKeys": {}, 43 + "compositePrimaryKeys": {}, 44 + "uniqueConstraints": {}, 45 + "checkConstraints": {} 46 + }, 47 + "oauth_states": { 48 + "name": "oauth_states", 49 + "columns": { 50 + "key": { 51 + "name": "key", 52 + "type": "text", 53 + "primaryKey": true, 54 + "notNull": true, 55 + "autoincrement": false 56 + }, 57 + "state": { 58 + "name": "state", 59 + "type": "text", 60 + "primaryKey": false, 61 + "notNull": true, 62 + "autoincrement": false 63 + }, 64 + "created_at": { 65 + "name": "created_at", 66 + "type": "text", 67 + "primaryKey": false, 68 + "notNull": true, 69 + "autoincrement": false, 70 + "default": "(datetime('now'))" 71 + } 72 + }, 73 + "indexes": {}, 74 + "foreignKeys": {}, 75 + "compositePrimaryKeys": {}, 76 + "uniqueConstraints": {}, 77 + "checkConstraints": {} 78 + }, 79 + "indexer_cursor": { 80 + "name": "indexer_cursor", 81 + "columns": { 82 + "id": { 83 + "name": "id", 84 + "type": "text", 85 + "primaryKey": true, 86 + "notNull": true, 87 + "autoincrement": false, 88 + "default": "'jetstream'" 89 + }, 90 + "cursor": { 91 + "name": "cursor", 92 + "type": "integer", 93 + "primaryKey": false, 94 + "notNull": true, 95 + "autoincrement": false 96 + }, 97 + "updated_at": { 98 + "name": "updated_at", 99 + "type": "text", 100 + "primaryKey": false, 101 + "notNull": true, 102 + "autoincrement": false, 103 + "default": "(datetime('now'))" 104 + } 105 + }, 106 + "indexes": {}, 107 + "foreignKeys": {}, 108 + "compositePrimaryKeys": {}, 109 + "uniqueConstraints": {}, 110 + "checkConstraints": {} 111 + }, 112 + "sphere_members": { 113 + "name": "sphere_members", 114 + "columns": { 115 + "sphere_id": { 116 + "name": "sphere_id", 117 + "type": "text", 118 + "primaryKey": false, 119 + "notNull": true, 120 + "autoincrement": false 121 + }, 122 + "did": { 123 + "name": "did", 124 + "type": "text", 125 + "primaryKey": false, 126 + "notNull": true, 127 + "autoincrement": false 128 + }, 129 + "role": { 130 + "name": "role", 131 + "type": "text", 132 + "primaryKey": false, 133 + "notNull": true, 134 + "autoincrement": false, 135 + "default": "'member'" 136 + }, 137 + "status": { 138 + "name": "status", 139 + "type": "text", 140 + "primaryKey": false, 141 + "notNull": true, 142 + "autoincrement": false, 143 + "default": "'invited'" 144 + }, 145 + "invited_by": { 146 + "name": "invited_by", 147 + "type": "text", 148 + "primaryKey": false, 149 + "notNull": false, 150 + "autoincrement": false 151 + }, 152 + "pds_uri": { 153 + "name": "pds_uri", 154 + "type": "text", 155 + "primaryKey": false, 156 + "notNull": false, 157 + "autoincrement": false 158 + }, 159 + "approval_pds_uri": { 160 + "name": "approval_pds_uri", 161 + "type": "text", 162 + "primaryKey": false, 163 + "notNull": false, 164 + "autoincrement": false 165 + }, 166 + "created_at": { 167 + "name": "created_at", 168 + "type": "text", 169 + "primaryKey": false, 170 + "notNull": true, 171 + "autoincrement": false, 172 + "default": "(datetime('now'))" 173 + } 174 + }, 175 + "indexes": { 176 + "idx_sphere_members_did": { 177 + "name": "idx_sphere_members_did", 178 + "columns": ["did"], 179 + "isUnique": false 180 + } 181 + }, 182 + "foreignKeys": { 183 + "sphere_members_sphere_id_spheres_id_fk": { 184 + "name": "sphere_members_sphere_id_spheres_id_fk", 185 + "tableFrom": "sphere_members", 186 + "tableTo": "spheres", 187 + "columnsFrom": ["sphere_id"], 188 + "columnsTo": ["id"], 189 + "onDelete": "no action", 190 + "onUpdate": "no action" 191 + } 192 + }, 193 + "compositePrimaryKeys": { 194 + "sphere_members_sphere_id_did_pk": { 195 + "columns": ["sphere_id", "did"], 196 + "name": "sphere_members_sphere_id_did_pk" 197 + } 198 + }, 199 + "uniqueConstraints": {}, 200 + "checkConstraints": {} 201 + }, 202 + "sphere_modules": { 203 + "name": "sphere_modules", 204 + "columns": { 205 + "sphere_id": { 206 + "name": "sphere_id", 207 + "type": "text", 208 + "primaryKey": false, 209 + "notNull": true, 210 + "autoincrement": false 211 + }, 212 + "module_name": { 213 + "name": "module_name", 214 + "type": "text", 215 + "primaryKey": false, 216 + "notNull": true, 217 + "autoincrement": false 218 + }, 219 + "enabled_at": { 220 + "name": "enabled_at", 221 + "type": "text", 222 + "primaryKey": false, 223 + "notNull": true, 224 + "autoincrement": false, 225 + "default": "(datetime('now'))" 226 + } 227 + }, 228 + "indexes": {}, 229 + "foreignKeys": { 230 + "sphere_modules_sphere_id_spheres_id_fk": { 231 + "name": "sphere_modules_sphere_id_spheres_id_fk", 232 + "tableFrom": "sphere_modules", 233 + "tableTo": "spheres", 234 + "columnsFrom": ["sphere_id"], 235 + "columnsTo": ["id"], 236 + "onDelete": "no action", 237 + "onUpdate": "no action" 238 + } 239 + }, 240 + "compositePrimaryKeys": { 241 + "sphere_modules_sphere_id_module_name_pk": { 242 + "columns": ["sphere_id", "module_name"], 243 + "name": "sphere_modules_sphere_id_module_name_pk" 244 + } 245 + }, 246 + "uniqueConstraints": {}, 247 + "checkConstraints": {} 248 + }, 249 + "spheres": { 250 + "name": "spheres", 251 + "columns": { 252 + "id": { 253 + "name": "id", 254 + "type": "text", 255 + "primaryKey": true, 256 + "notNull": true, 257 + "autoincrement": false 258 + }, 259 + "handle": { 260 + "name": "handle", 261 + "type": "text", 262 + "primaryKey": false, 263 + "notNull": true, 264 + "autoincrement": false 265 + }, 266 + "name": { 267 + "name": "name", 268 + "type": "text", 269 + "primaryKey": false, 270 + "notNull": true, 271 + "autoincrement": false 272 + }, 273 + "description": { 274 + "name": "description", 275 + "type": "text", 276 + "primaryKey": false, 277 + "notNull": false, 278 + "autoincrement": false 279 + }, 280 + "visibility": { 281 + "name": "visibility", 282 + "type": "text", 283 + "primaryKey": false, 284 + "notNull": true, 285 + "autoincrement": false, 286 + "default": "'public'" 287 + }, 288 + "write_access": { 289 + "name": "write_access", 290 + "type": "text", 291 + "primaryKey": false, 292 + "notNull": true, 293 + "autoincrement": false, 294 + "default": "'open'" 295 + }, 296 + "owner_did": { 297 + "name": "owner_did", 298 + "type": "text", 299 + "primaryKey": false, 300 + "notNull": true, 301 + "autoincrement": false 302 + }, 303 + "pds_uri": { 304 + "name": "pds_uri", 305 + "type": "text", 306 + "primaryKey": false, 307 + "notNull": false, 308 + "autoincrement": false 309 + }, 310 + "created_at": { 311 + "name": "created_at", 312 + "type": "text", 313 + "primaryKey": false, 314 + "notNull": true, 315 + "autoincrement": false, 316 + "default": "(datetime('now'))" 317 + }, 318 + "updated_at": { 319 + "name": "updated_at", 320 + "type": "text", 321 + "primaryKey": false, 322 + "notNull": true, 323 + "autoincrement": false, 324 + "default": "(datetime('now'))" 325 + } 326 + }, 327 + "indexes": { 328 + "spheres_handle_unique": { 329 + "name": "spheres_handle_unique", 330 + "columns": ["handle"], 331 + "isUnique": true 332 + } 333 + }, 334 + "foreignKeys": {}, 335 + "compositePrimaryKeys": {}, 336 + "uniqueConstraints": {}, 337 + "checkConstraints": {} 338 + }, 339 + "feature_request_comment_votes": { 340 + "name": "feature_request_comment_votes", 341 + "columns": { 342 + "comment_id": { 343 + "name": "comment_id", 344 + "type": "text", 345 + "primaryKey": false, 346 + "notNull": true, 347 + "autoincrement": false 348 + }, 349 + "author_did": { 350 + "name": "author_did", 351 + "type": "text", 352 + "primaryKey": false, 353 + "notNull": true, 354 + "autoincrement": false 355 + }, 356 + "pds_uri": { 357 + "name": "pds_uri", 358 + "type": "text", 359 + "primaryKey": false, 360 + "notNull": false, 361 + "autoincrement": false 362 + }, 363 + "created_at": { 364 + "name": "created_at", 365 + "type": "text", 366 + "primaryKey": false, 367 + "notNull": true, 368 + "autoincrement": false, 369 + "default": "(datetime('now'))" 370 + } 371 + }, 372 + "indexes": { 373 + "idx_feature_request_comment_votes_comment": { 374 + "name": "idx_feature_request_comment_votes_comment", 375 + "columns": ["comment_id"], 376 + "isUnique": false 377 + } 378 + }, 379 + "foreignKeys": { 380 + "feature_request_comment_votes_comment_id_feature_request_comments_id_fk": { 381 + "name": "feature_request_comment_votes_comment_id_feature_request_comments_id_fk", 382 + "tableFrom": "feature_request_comment_votes", 383 + "tableTo": "feature_request_comments", 384 + "columnsFrom": ["comment_id"], 385 + "columnsTo": ["id"], 386 + "onDelete": "no action", 387 + "onUpdate": "no action" 388 + } 389 + }, 390 + "compositePrimaryKeys": { 391 + "feature_request_comment_votes_comment_id_author_did_pk": { 392 + "columns": ["comment_id", "author_did"], 393 + "name": "feature_request_comment_votes_comment_id_author_did_pk" 394 + } 395 + }, 396 + "uniqueConstraints": {}, 397 + "checkConstraints": {} 398 + }, 399 + "feature_request_comments": { 400 + "name": "feature_request_comments", 401 + "columns": { 402 + "id": { 403 + "name": "id", 404 + "type": "text", 405 + "primaryKey": true, 406 + "notNull": true, 407 + "autoincrement": false 408 + }, 409 + "request_id": { 410 + "name": "request_id", 411 + "type": "text", 412 + "primaryKey": false, 413 + "notNull": true, 414 + "autoincrement": false 415 + }, 416 + "author_did": { 417 + "name": "author_did", 418 + "type": "text", 419 + "primaryKey": false, 420 + "notNull": true, 421 + "autoincrement": false 422 + }, 423 + "content": { 424 + "name": "content", 425 + "type": "text", 426 + "primaryKey": false, 427 + "notNull": true, 428 + "autoincrement": false 429 + }, 430 + "pds_uri": { 431 + "name": "pds_uri", 432 + "type": "text", 433 + "primaryKey": false, 434 + "notNull": false, 435 + "autoincrement": false 436 + }, 437 + "updated_at": { 438 + "name": "updated_at", 439 + "type": "text", 440 + "primaryKey": false, 441 + "notNull": true, 442 + "autoincrement": false, 443 + "default": "(datetime('now'))" 444 + }, 445 + "hidden_at": { 446 + "name": "hidden_at", 447 + "type": "text", 448 + "primaryKey": false, 449 + "notNull": false, 450 + "autoincrement": false 451 + }, 452 + "moderated_by": { 453 + "name": "moderated_by", 454 + "type": "text", 455 + "primaryKey": false, 456 + "notNull": false, 457 + "autoincrement": false 458 + } 459 + }, 460 + "indexes": { 461 + "idx_feature_request_comments_request": { 462 + "name": "idx_feature_request_comments_request", 463 + "columns": ["request_id"], 464 + "isUnique": false 465 + }, 466 + "idx_feature_request_comments_author_request": { 467 + "name": "idx_feature_request_comments_author_request", 468 + "columns": ["author_did", "request_id"], 469 + "isUnique": false 470 + } 471 + }, 472 + "foreignKeys": { 473 + "feature_request_comments_request_id_feature_requests_id_fk": { 474 + "name": "feature_request_comments_request_id_feature_requests_id_fk", 475 + "tableFrom": "feature_request_comments", 476 + "tableTo": "feature_requests", 477 + "columnsFrom": ["request_id"], 478 + "columnsTo": ["id"], 479 + "onDelete": "no action", 480 + "onUpdate": "no action" 481 + } 482 + }, 483 + "compositePrimaryKeys": {}, 484 + "uniqueConstraints": {}, 485 + "checkConstraints": {} 486 + }, 487 + "feature_request_statuses": { 488 + "name": "feature_request_statuses", 489 + "columns": { 490 + "id": { 491 + "name": "id", 492 + "type": "text", 493 + "primaryKey": true, 494 + "notNull": true, 495 + "autoincrement": false 496 + }, 497 + "request_id": { 498 + "name": "request_id", 499 + "type": "text", 500 + "primaryKey": false, 501 + "notNull": true, 502 + "autoincrement": false 503 + }, 504 + "author_did": { 505 + "name": "author_did", 506 + "type": "text", 507 + "primaryKey": false, 508 + "notNull": true, 509 + "autoincrement": false 510 + }, 511 + "status": { 512 + "name": "status", 513 + "type": "text", 514 + "primaryKey": false, 515 + "notNull": true, 516 + "autoincrement": false 517 + }, 518 + "pds_uri": { 519 + "name": "pds_uri", 520 + "type": "text", 521 + "primaryKey": false, 522 + "notNull": false, 523 + "autoincrement": false 524 + } 525 + }, 526 + "indexes": { 527 + "idx_feature_request_statuses_request": { 528 + "name": "idx_feature_request_statuses_request", 529 + "columns": ["request_id"], 530 + "isUnique": false 531 + } 532 + }, 533 + "foreignKeys": { 534 + "feature_request_statuses_request_id_feature_requests_id_fk": { 535 + "name": "feature_request_statuses_request_id_feature_requests_id_fk", 536 + "tableFrom": "feature_request_statuses", 537 + "tableTo": "feature_requests", 538 + "columnsFrom": ["request_id"], 539 + "columnsTo": ["id"], 540 + "onDelete": "no action", 541 + "onUpdate": "no action" 542 + } 543 + }, 544 + "compositePrimaryKeys": {}, 545 + "uniqueConstraints": {}, 546 + "checkConstraints": {} 547 + }, 548 + "feature_request_votes": { 549 + "name": "feature_request_votes", 550 + "columns": { 551 + "request_id": { 552 + "name": "request_id", 553 + "type": "text", 554 + "primaryKey": false, 555 + "notNull": true, 556 + "autoincrement": false 557 + }, 558 + "author_did": { 559 + "name": "author_did", 560 + "type": "text", 561 + "primaryKey": false, 562 + "notNull": true, 563 + "autoincrement": false 564 + }, 565 + "pds_uri": { 566 + "name": "pds_uri", 567 + "type": "text", 568 + "primaryKey": false, 569 + "notNull": false, 570 + "autoincrement": false 571 + }, 572 + "created_at": { 573 + "name": "created_at", 574 + "type": "text", 575 + "primaryKey": false, 576 + "notNull": true, 577 + "autoincrement": false, 578 + "default": "(datetime('now'))" 579 + } 580 + }, 581 + "indexes": { 582 + "idx_feature_request_votes_request": { 583 + "name": "idx_feature_request_votes_request", 584 + "columns": ["request_id"], 585 + "isUnique": false 586 + } 587 + }, 588 + "foreignKeys": { 589 + "feature_request_votes_request_id_feature_requests_id_fk": { 590 + "name": "feature_request_votes_request_id_feature_requests_id_fk", 591 + "tableFrom": "feature_request_votes", 592 + "tableTo": "feature_requests", 593 + "columnsFrom": ["request_id"], 594 + "columnsTo": ["id"], 595 + "onDelete": "no action", 596 + "onUpdate": "no action" 597 + } 598 + }, 599 + "compositePrimaryKeys": { 600 + "feature_request_votes_request_id_author_did_pk": { 601 + "columns": ["request_id", "author_did"], 602 + "name": "feature_request_votes_request_id_author_did_pk" 603 + } 604 + }, 605 + "uniqueConstraints": {}, 606 + "checkConstraints": {} 607 + }, 608 + "feature_requests": { 609 + "name": "feature_requests", 610 + "columns": { 611 + "id": { 612 + "name": "id", 613 + "type": "text", 614 + "primaryKey": true, 615 + "notNull": true, 616 + "autoincrement": false 617 + }, 618 + "sphere_id": { 619 + "name": "sphere_id", 620 + "type": "text", 621 + "primaryKey": false, 622 + "notNull": true, 623 + "autoincrement": false 624 + }, 625 + "number": { 626 + "name": "number", 627 + "type": "integer", 628 + "primaryKey": false, 629 + "notNull": true, 630 + "autoincrement": false 631 + }, 632 + "author_did": { 633 + "name": "author_did", 634 + "type": "text", 635 + "primaryKey": false, 636 + "notNull": true, 637 + "autoincrement": false 638 + }, 639 + "title": { 640 + "name": "title", 641 + "type": "text", 642 + "primaryKey": false, 643 + "notNull": true, 644 + "autoincrement": false 645 + }, 646 + "description": { 647 + "name": "description", 648 + "type": "text", 649 + "primaryKey": false, 650 + "notNull": true, 651 + "autoincrement": false 652 + }, 653 + "category": { 654 + "name": "category", 655 + "type": "text", 656 + "primaryKey": false, 657 + "notNull": true, 658 + "autoincrement": false, 659 + "default": "'general'" 660 + }, 661 + "status": { 662 + "name": "status", 663 + "type": "text", 664 + "primaryKey": false, 665 + "notNull": true, 666 + "autoincrement": false, 667 + "default": "'requested'" 668 + }, 669 + "duplicate_of_id": { 670 + "name": "duplicate_of_id", 671 + "type": "text", 672 + "primaryKey": false, 673 + "notNull": false, 674 + "autoincrement": false 675 + }, 676 + "pds_uri": { 677 + "name": "pds_uri", 678 + "type": "text", 679 + "primaryKey": false, 680 + "notNull": false, 681 + "autoincrement": false 682 + }, 683 + "hidden_at": { 684 + "name": "hidden_at", 685 + "type": "text", 686 + "primaryKey": false, 687 + "notNull": false, 688 + "autoincrement": false 689 + }, 690 + "moderated_by": { 691 + "name": "moderated_by", 692 + "type": "text", 693 + "primaryKey": false, 694 + "notNull": false, 695 + "autoincrement": false 696 + }, 697 + "updated_at": { 698 + "name": "updated_at", 699 + "type": "text", 700 + "primaryKey": false, 701 + "notNull": true, 702 + "autoincrement": false, 703 + "default": "(datetime('now'))" 704 + } 705 + }, 706 + "indexes": { 707 + "idx_feature_requests_sphere_number": { 708 + "name": "idx_feature_requests_sphere_number", 709 + "columns": ["sphere_id", "number"], 710 + "isUnique": true 711 + }, 712 + "idx_feature_requests_sphere": { 713 + "name": "idx_feature_requests_sphere", 714 + "columns": ["sphere_id"], 715 + "isUnique": false 716 + }, 717 + "idx_feature_requests_status": { 718 + "name": "idx_feature_requests_status", 719 + "columns": ["status"], 720 + "isUnique": false 721 + }, 722 + "idx_feature_requests_category": { 723 + "name": "idx_feature_requests_category", 724 + "columns": ["category"], 725 + "isUnique": false 726 + } 727 + }, 728 + "foreignKeys": { 729 + "feature_requests_sphere_id_spheres_id_fk": { 730 + "name": "feature_requests_sphere_id_spheres_id_fk", 731 + "tableFrom": "feature_requests", 732 + "tableTo": "spheres", 733 + "columnsFrom": ["sphere_id"], 734 + "columnsTo": ["id"], 735 + "onDelete": "no action", 736 + "onUpdate": "no action" 737 + } 738 + }, 739 + "compositePrimaryKeys": {}, 740 + "uniqueConstraints": {}, 741 + "checkConstraints": {} 742 + }, 743 + "feed_posts": { 744 + "name": "feed_posts", 745 + "columns": { 746 + "id": { 747 + "name": "id", 748 + "type": "text", 749 + "primaryKey": true, 750 + "notNull": true, 751 + "autoincrement": false 752 + }, 753 + "author_did": { 754 + "name": "author_did", 755 + "type": "text", 756 + "primaryKey": false, 757 + "notNull": true, 758 + "autoincrement": false 759 + }, 760 + "content": { 761 + "name": "content", 762 + "type": "text", 763 + "primaryKey": false, 764 + "notNull": true, 765 + "autoincrement": false 766 + }, 767 + "parent_id": { 768 + "name": "parent_id", 769 + "type": "text", 770 + "primaryKey": false, 771 + "notNull": false, 772 + "autoincrement": false 773 + }, 774 + "pds_uri": { 775 + "name": "pds_uri", 776 + "type": "text", 777 + "primaryKey": false, 778 + "notNull": false, 779 + "autoincrement": false 780 + }, 781 + "updated_at": { 782 + "name": "updated_at", 783 + "type": "text", 784 + "primaryKey": false, 785 + "notNull": true, 786 + "autoincrement": false, 787 + "default": "(datetime('now'))" 788 + } 789 + }, 790 + "indexes": { 791 + "idx_feed_posts_parent": { 792 + "name": "idx_feed_posts_parent", 793 + "columns": ["parent_id"], 794 + "isUnique": false 795 + } 796 + }, 797 + "foreignKeys": {}, 798 + "compositePrimaryKeys": {}, 799 + "uniqueConstraints": {}, 800 + "checkConstraints": {} 801 + } 802 + }, 803 + "views": {}, 804 + "enums": {}, 805 + "_meta": { 806 + "schemas": {}, 807 + "tables": {}, 808 + "columns": {} 809 + }, 810 + "internal": { 811 + "indexes": {} 812 + } 813 + }
+7
drizzle/meta/_journal.json
··· 8 8 "when": 1774360860027, 9 9 "tag": "0000_brave_goliath", 10 10 "breakpoints": true 11 + }, 12 + { 13 + "idx": 1, 14 + "version": "6", 15 + "when": 1774458610448, 16 + "tag": "0001_hard_vulture", 17 + "breakpoints": true 11 18 } 12 19 ] 13 20 }
+5
packages/core/src/pds.ts
··· 8 8 return TID.nextStr(); 9 9 } 10 10 11 + export function tidToDate(tid: string): string { 12 + const t = TID.fromStr(tid); 13 + return new Date(Math.floor(t.timestamp() / 1000)).toISOString(); 14 + } 15 + 11 16 export async function putPdsRecord<C extends keyof PdsRecordMap>( 12 17 session: OAuthSession, 13 18 collection: C,
+11 -13
packages/feature-requests/src/api/comments.ts
··· 4 4 import { eq, and, count, sql, inArray, desc, asc } from "@exosphere/core/db/drizzle"; 5 5 import { requireAuth, type AuthEnv } from "@exosphere/core/auth"; 6 6 import { getActiveMemberRole, isAdminOrOwner } from "@exosphere/core/sphere"; 7 - import { putPdsRecord, deletePdsRecord, generateRkey } from "@exosphere/core/pds"; 7 + import { putPdsRecord, deletePdsRecord, generateRkey, tidToDate } from "@exosphere/core/pds"; 8 8 import { resolveDidHandles } from "@exosphere/core/identity"; 9 9 import type { SphereEnv } from "@exosphere/core/types"; 10 10 import { ··· 64 64 } 65 65 66 66 // When the request is closed (done/not-planned), hide comments posted after the closing date 67 - let cutoffDate: string | null = null; 67 + let cutoffId: string | null = null; 68 68 if ( 69 69 request.status === "done" || 70 70 request.status === "not-planned" || 71 71 request.status === "duplicate" 72 72 ) { 73 73 const closedStatus = db 74 - .select({ createdAt: featureRequestStatuses.createdAt }) 74 + .select({ id: featureRequestStatuses.id }) 75 75 .from(featureRequestStatuses) 76 76 .where( 77 77 and( ··· 79 79 inArray(featureRequestStatuses.status, ["done", "not-planned", "duplicate"]), 80 80 ), 81 81 ) 82 - .orderBy(sql`${featureRequestStatuses.createdAt} desc`) 82 + .orderBy(sql`${featureRequestStatuses.id} desc`) 83 83 .limit(1) 84 84 .get(); 85 - cutoffDate = closedStatus?.createdAt ?? null; 85 + cutoffId = closedStatus?.id ?? null; 86 86 } 87 87 88 88 const notHidden = sql`${featureRequestComments.hiddenAt} is null`; 89 - const whereCondition = cutoffDate 89 + const whereCondition = cutoffId 90 90 ? and( 91 91 eq(featureRequestComments.requestId, requestId), 92 - sql`${featureRequestComments.createdAt} <= ${cutoffDate}`, 92 + sql`${featureRequestComments.id} <= ${cutoffId}`, 93 93 notHidden, 94 94 ) 95 95 : and(eq(featureRequestComments.requestId, requestId), notHidden); ··· 102 102 authorDid: featureRequestComments.authorDid, 103 103 content: featureRequestComments.content, 104 104 pdsUri: featureRequestComments.pdsUri, 105 - createdAt: featureRequestComments.createdAt, 106 105 updatedAt: featureRequestComments.updatedAt, 107 106 voteCount: voteCountCol, 108 107 }) ··· 113 112 ) 114 113 .where(whereCondition) 115 114 .groupBy(featureRequestComments.id) 116 - .orderBy( 117 - sortBy === "votes" ? orderDir(voteCountCol) : orderDir(featureRequestComments.createdAt), 118 - ) 115 + .orderBy(sortBy === "votes" ? orderDir(voteCountCol) : orderDir(featureRequestComments.id)) 119 116 .all(); 120 117 121 118 const handleMap = await resolveDidHandles(rows.map((r) => r.authorDid)); 122 119 const comments = rows.map((r) => ({ 123 120 ...r, 121 + createdAt: tidToDate(r.id), 124 122 authorHandle: handleMap.get(r.authorDid) ?? null, 125 123 })); 126 124 ··· 194 192 .where(eq(featureRequestComments.id, id)) 195 193 .get(); 196 194 197 - return c.json({ comment }, 201); 195 + return c.json({ comment: comment ? { ...comment, createdAt: tidToDate(id) } : comment }, 201); 198 196 }); 199 197 200 198 // Update own comment (author only) ··· 246 244 .where(eq(featureRequestComments.id, id)) 247 245 .get(); 248 246 249 - return c.json({ comment: updated }); 247 + return c.json({ comment: updated ? { ...updated, createdAt: tidToDate(id) } : updated }); 250 248 }); 251 249 252 250 // Delete own comment or admin-moderate a comment
+9 -7
packages/feature-requests/src/api/requests.ts
··· 4 4 import { eq, and, count, sql, inArray, like, desc, asc } from "@exosphere/core/db/drizzle"; 5 5 import { requireAuth, type AuthEnv } from "@exosphere/core/auth"; 6 6 import { getActiveMemberRole, isAdminOrOwner } from "@exosphere/core/sphere"; 7 - import { putPdsRecord, deletePdsRecord, generateRkey } from "@exosphere/core/pds"; 7 + import { putPdsRecord, deletePdsRecord, generateRkey, tidToDate } from "@exosphere/core/pds"; 8 8 import { resolveDidHandles } from "@exosphere/core/identity"; 9 9 import type { SphereEnv } from "@exosphere/core/types"; 10 10 import { featureRequests, featureRequestVotes, featureRequestComments } from "../db/schema.ts"; ··· 37 37 status: featureRequests.status, 38 38 duplicateOfId: featureRequests.duplicateOfId, 39 39 pdsUri: featureRequests.pdsUri, 40 - createdAt: featureRequests.createdAt, 41 40 updatedAt: featureRequests.updatedAt, 42 41 voteCount: count(featureRequestVotes.authorDid), 43 42 commentCount: ··· 87 86 const handleMap = await resolveDidHandles([row.authorDid]); 88 87 const authorHandle = handleMap.get(row.authorDid) ?? null; 89 88 90 - return c.json({ featureRequest: { ...row, authorHandle }, duplicateOf, duplicateCount }); 89 + return c.json({ 90 + featureRequest: { ...row, createdAt: tidToDate(row.id), authorHandle }, 91 + duplicateOf, 92 + duplicateCount, 93 + }); 91 94 }); 92 95 93 96 app.get("/", (c) => { ··· 124 127 status: featureRequests.status, 125 128 duplicateOfId: featureRequests.duplicateOfId, 126 129 pdsUri: featureRequests.pdsUri, 127 - createdAt: featureRequests.createdAt, 128 130 updatedAt: featureRequests.updatedAt, 129 131 voteCount: voteCountCol, 130 132 commentCount: ··· 136 138 .leftJoin(featureRequestVotes, eq(featureRequestVotes.requestId, featureRequests.id)) 137 139 .where(and(...conditions)) 138 140 .groupBy(featureRequests.id) 139 - .orderBy(sortBy === "votes" ? orderDir(voteCountCol) : orderDir(featureRequests.createdAt)) 141 + .orderBy(sortBy === "votes" ? orderDir(voteCountCol) : orderDir(featureRequests.id)) 140 142 .all(); 141 - return c.json({ featureRequests: rows }); 143 + return c.json({ featureRequests: rows.map((r) => ({ ...r, createdAt: tidToDate(r.id) })) }); 142 144 }); 143 145 144 146 app.post("/", requireAuth, async (c) => { ··· 178 180 pdsUri, 179 181 }); 180 182 181 - return c.json({ featureRequest: row }, 201); 183 + return c.json({ featureRequest: row ? { ...row, createdAt: tidToDate(id) } : row }, 201); 182 184 }); 183 185 184 186 // Author-only: delete own feature request (local DB + PDS)
+3 -3
packages/feature-requests/src/api/statuses.ts
··· 4 4 import { eq, and, sql } from "@exosphere/core/db/drizzle"; 5 5 import { requireAuth, type AuthEnv } from "@exosphere/core/auth"; 6 6 import { getActiveMemberRole, isAdminOrOwner } from "@exosphere/core/sphere"; 7 - import { putPdsRecord, generateRkey } from "@exosphere/core/pds"; 7 + import { putPdsRecord, generateRkey, tidToDate } from "@exosphere/core/pds"; 8 8 import { resolveDidHandles } from "@exosphere/core/identity"; 9 9 import type { SphereEnv } from "@exosphere/core/types"; 10 10 import { featureRequests, featureRequestStatuses } from "../db/schema.ts"; ··· 194 194 id: featureRequestStatuses.id, 195 195 authorDid: featureRequestStatuses.authorDid, 196 196 status: featureRequestStatuses.status, 197 - createdAt: featureRequestStatuses.createdAt, 198 197 }) 199 198 .from(featureRequestStatuses) 200 199 .where(eq(featureRequestStatuses.requestId, id)) 201 - .orderBy(sql`${featureRequestStatuses.createdAt} desc`) 200 + .orderBy(sql`${featureRequestStatuses.id} desc`) 202 201 .all(); 203 202 204 203 const handleMap = await resolveDidHandles(rows.map((r) => r.authorDid)); 205 204 const statuses = rows.map((r) => ({ 206 205 ...r, 206 + createdAt: tidToDate(r.id), 207 207 authorHandle: handleMap.get(r.authorDid) ?? null, 208 208 })); 209 209
+3 -1
packages/feature-requests/src/db/operations.ts
··· 1 1 import { getDb } from "@exosphere/core/db"; 2 2 import { eq, and, inArray, max } from "@exosphere/core/db/drizzle"; 3 + import { tidToDate } from "@exosphere/core/pds"; 3 4 import type { ModerationHandler } from "@exosphere/core/sphere"; 4 5 import { 5 6 featureRequests, ··· 100 101 content: string; 101 102 pdsUri: string | null; 102 103 }): void { 104 + const updatedAt = tidToDate(params.id); 103 105 getDb() 104 106 .insert(featureRequestComments) 105 - .values(params) 107 + .values({ ...params, updatedAt }) 106 108 .onConflictDoUpdate({ 107 109 target: featureRequestComments.id, 108 110 set: { content: params.content, updatedAt: new Date().toISOString() },
-10
packages/feature-requests/src/db/schema.ts
··· 32 32 pdsUri: text("pds_uri"), 33 33 hiddenAt: text("hidden_at"), 34 34 moderatedBy: text("moderated_by"), 35 - createdAt: text("created_at") 36 - .notNull() 37 - .default(sql`(datetime('now'))`), 38 35 updatedAt: text("updated_at") 39 36 .notNull() 40 37 .default(sql`(datetime('now'))`), ··· 43 40 uniqueIndex("idx_feature_requests_sphere_number").on(table.sphereId, table.number), 44 41 index("idx_feature_requests_sphere").on(table.sphereId), 45 42 index("idx_feature_requests_status").on(table.status), 46 - index("idx_feature_requests_created").on(table.createdAt), 47 43 index("idx_feature_requests_category").on(table.category), 48 44 ], 49 45 ); ··· 76 72 authorDid: text("author_did").notNull(), 77 73 content: text("content").notNull(), 78 74 pdsUri: text("pds_uri"), 79 - createdAt: text("created_at") 80 - .notNull() 81 - .default(sql`(datetime('now'))`), 82 75 updatedAt: text("updated_at") 83 76 .notNull() 84 77 .default(sql`(datetime('now'))`), ··· 119 112 authorDid: text("author_did").notNull(), 120 113 status: text("status", { enum: [...statuses] }).notNull(), 121 114 pdsUri: text("pds_uri"), 122 - createdAt: text("created_at") 123 - .notNull() 124 - .default(sql`(datetime('now'))`), 125 115 }, 126 116 (table) => [index("idx_feature_request_statuses_request").on(table.requestId)], 127 117 );
+2
packages/feature-requests/src/types.ts
··· 12 12 13 13 /** Shape returned by the GET /feature-requests list/detail endpoints (includes vote count). */ 14 14 export type FeatureRequestListItem = FeatureRequest & { 15 + createdAt: string; 15 16 voteCount: number; 16 17 commentCount: number; 17 18 authorHandle?: string | null; ··· 19 20 20 21 /** Shape returned by the GET comments endpoint (includes vote count and resolved handle). */ 21 22 export type FeatureRequestCommentListItem = FeatureRequestComment & { 23 + createdAt: string; 22 24 voteCount: number; 23 25 authorHandle: string | null; 24 26 };
+2 -2
packages/feature-requests/src/ui/api/comments.ts
··· 14 14 } 15 15 16 16 export function createComment(requestId: string, content: string) { 17 - return moduleFetch<{ comment: FeatureRequestComment }>( 17 + return moduleFetch<{ comment: FeatureRequestComment & { createdAt: string } }>( 18 18 `/feature-requests/${encodeURIComponent(requestId)}/comments`, 19 19 { 20 20 method: "POST", ··· 25 25 } 26 26 27 27 export function updateComment(id: string, content: string) { 28 - return moduleFetch<{ comment: FeatureRequestComment }>( 28 + return moduleFetch<{ comment: FeatureRequestComment & { createdAt: string } }>( 29 29 `/feature-requests/comments/${encodeURIComponent(id)}`, 30 30 { 31 31 method: "PUT",
+1 -7
packages/feeds/src/db/schema.ts
··· 9 9 content: text("content").notNull(), 10 10 parentId: text("parent_id"), 11 11 pdsUri: text("pds_uri"), 12 - createdAt: text("created_at") 13 - .notNull() 14 - .default(sql`(datetime('now'))`), 15 12 updatedAt: text("updated_at") 16 13 .notNull() 17 14 .default(sql`(datetime('now'))`), 18 15 }, 19 - (table) => [ 20 - index("idx_feed_posts_parent").on(table.parentId), 21 - index("idx_feed_posts_created").on(table.createdAt), 22 - ], 16 + (table) => [index("idx_feed_posts_parent").on(table.parentId)], 23 17 );
-1
packages/feeds/src/ui/feed.tsx
··· 5 5 id: string; 6 6 content: string; 7 7 author_did: string; 8 - created_at: string; 9 8 } 10 9 11 10 export function Feed() {