{"id":13516957,"url":"https://github.com/KejawenLab/SemartApiSkeleton","last_synced_at":"2025-03-31T07:30:48.972Z","repository":{"id":39750358,"uuid":"268249921","full_name":"KejawenLab/SemartApiSkeleton","owner":"KejawenLab","description":"Blazing Fast Admin and Api Generator for PHP","archived":false,"fork":false,"pushed_at":"2025-02-06T09:14:09.000Z","size":47115,"stargazers_count":70,"open_issues_count":1,"forks_count":16,"subscribers_count":4,"default_branch":"main","last_synced_at":"2025-03-24T08:08:52.914Z","etag":null,"topics":["kejawenlab","php","semart","semart-api-skeleton","symfony","symfony-api","symfony-skeleton","symfony5","symfony6"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/KejawenLab.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-05-31T09:41:34.000Z","updated_at":"2025-02-06T09:14:12.000Z","dependencies_parsed_at":"2023-02-06T08:15:19.687Z","dependency_job_id":null,"html_url":"https://github.com/KejawenLab/SemartApiSkeleton","commit_stats":null,"previous_names":[],"tags_count":96,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/KejawenLab%2FSemartApiSkeleton","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/KejawenLab%2FSemartApiSkeleton/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/KejawenLab%2FSemartApiSkeleton/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/KejawenLab%2FSemartApiSkeleton/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/KejawenLab","download_url":"https://codeload.github.com/KejawenLab/SemartApiSkeleton/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246432915,"owners_count":20776485,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["kejawenlab","php","semart","semart-api-skeleton","symfony","symfony-api","symfony-skeleton","symfony5","symfony6"],"created_at":"2024-08-01T05:01:27.745Z","updated_at":"2025-03-31T07:30:43.964Z","avatar_url":"https://github.com/KejawenLab.png","language":"JavaScript","funding_links":[],"categories":["JavaScript"],"sub_categories":[],"readme":"# SemartApiSkeleton\n\n\u003e\n\u003e SemartApiSkeleton adalah solusi untuk membangun aplikasi secara super cepat, sangat fleksibel dan luar biasa mudah untuk aplikasi berbasis Admin maupun Api\n\u003e \n\u003e SemartApiSkeleton menggunakan `swoole` sebagai [PHP Runtime](https://symfony.com/doc/current/components/runtime.html) untuk menjalankan PHP dengan model long pooling sebagaimana NodeJs, Golang atau sejenisnya.\n\u003e\n\n## Requirement\n\n- [Docker](https://docs.docker.com/engine)\n\n- [Docker Compose](https://docs.docker.com/compose)\n\n## Install\n\n### Pre Step\n\n\u003e \n\u003e Clone dan Generate PKI (Public Key Infrastucture)\n\u003e\n\n```bash\ngit clone https://github.com/KejawenLab/SemartApiSkeleton\ncd SemartApiSkeleton\nmkdir -p config/jwt\nopenssl genpkey -out config/jwt/private.pem -aes256 -algorithm rsa -pkeyopt rsa_keygen_bits:4096\n#Jangan lupa untuk mengingat passphrase yang diinput\nopenssl pkey -in config/jwt/private.pem -out config/jwt/public.pem -pubout\n```\n\n### Docker Install\n\n\u003e\n\u003e Install menggunakan metode Docker adalah cara tercepat untuk memulai tanpa perlu install dependencies terlebih dahulu\n\u003e\n\u003e * Ubah file `.env.template` menjadi file `.env`\n\u003e\n\u003e * Ubah isi file `.env` sesuai dengan kebutuhan terutama pada `JWT_PASSPHRASE`, berikut contoh konfigurasinya\n\n```dotenv\n# In all environments, the following files are loaded if they exist,\n# the latter taking precedence over the former:\n#\n#  * .env                contains default values for the environment variables needed by the app\n#  * .env.local          uncommitted file with local overrides\n#  * .env.$APP_ENV       committed environment-specific defaults\n#  * .env.$APP_ENV.local uncommitted environment-specific overrides\n#\n# Real environment variables win over .env files.\n#\n# DO NOT DEFINE PRODUCTION SECRETS IN THIS FILE NOR IN ANY OTHER COMMITTED FILES.\n#\n# Run \"composer dump-env prod\" to compile .env files for production use (requires symfony/flex \u003e=1.2).\n# https://symfony.com/doc/current/best_practices.html#use-environment-variables-for-infrastructure-configuration\n\nAPP_RUNTIME=Runtime\\Swoole\\Runtime\n\n###\u003e symfony/framework-bundle ###\nAPP_ENV=dev\nAPP_SECRET=ykWmyQ9xVGbn+vQB2gzCWg==\n#TRUSTED_PROXIES=127.0.0.0/8,10.0.0.0/8,172.16.0.0/12,192.168.0.0/16\n#TRUSTED_HOSTS='^(localhost|example\\.com)$'\n###\u003c symfony/framework-bundle ###\n\n###\u003e lexik/jwt-authentication-bundle ###\nJWT_SECRET_KEY=%kernel.project_dir%/config/jwt/private.pem\nJWT_PUBLIC_KEY=%kernel.project_dir%/config/jwt/public.pem\nJWT_PASSPHRASE=CHANGEME-TO-VALUE-THAT-YOU-PROVIDE-WHEN-GENERATING-PRIVATE-KEY\n###\u003c lexik/jwt-authentication-bundle ###\n\n###\u003e snc/redis-bundle ###\n# passwords that contain special characters (@, %, :, +) must be urlencoded\nREDIS_URL=redis://session\n###\u003c snc/redis-bundle ###\n\n###\u003e CUSTOM ###\nNGINX_WEBROOT=/semart/public\nSWOOLE_HOST=\"0.0.0.0\"\nSWOOLE_PORT=9501\nAPP_SUPER_ADMIN=SPRADM\nAPP_TITLE=\"Semart Api Skeleton\"\nAPP_DESCRIPTION=\"Semart Api Skeleton Application\"\nAPP_VERSION=1@dev\nAPP_UPLOAD_DIR=%kernel.project_dir%/storage\nAPP_MEDIA_PREFIX=/medias\n###\u003c CUSTOM ###\n\n###\u003e doctrine/doctrine-bundle ###\nDATABASE_DRIVER=pdo_pgsql\nDATABASE_CHARSET=utf8\nDATABASE_USER=semart\nDATABASE_PASSWORD=CHANGEME-TO-VALUE-PROVIDED-BY-SEMART-ENCRYPT-COMMAND\nDATABASE_NAME=semart_skeleton\nDATABASE_HOST=db\nDATABASE_PORT=5432\n# Format described at https://www.doctrine-project.org/projects/doctrine-dbal/en/latest/reference/configuration.html#connecting-using-a-url\n# For an SQLite database, use: \"sqlite:///%kernel.project_dir%/var/data.db\"\n# For a PostgreSQL database, use: \"postgresql://db_user:db_password@127.0.0.1:5432/db_name?serverVersion=11\u0026charset=utf8\"\n# IMPORTANT: You MUST configure your server version, either here or in config/packages/doctrine.yaml\n# DATABASE_URL=mysql://db_user:db_password@127.0.0.1:3306/db_name?serverVersion=5.7\n###\u003c doctrine/doctrine-bundle ###\n\n###\u003e nelmio/cors-bundle ###\nCORS_ALLOW_ORIGIN='^https?://(localhost|127\\.0\\.0\\.1)(:[0-9]+)?$'\n###\u003c nelmio/cors-bundle ###\n\n###\u003e symfony/messenger ###\n# Choose one of the transports below\nMESSENGER_TRANSPORT_DSN=amqp://guest:guest@messenger:5672/%2f/messages\n# MESSENGER_TRANSPORT_DSN=doctrine://default\n# MESSENGER_TRANSPORT_DSN=redis://localhost:6379/messages\n###\u003c symfony/messenger ###\n\n```\n\n\u003e\n\u003e * Karena Semart Api Skeleton menggunakan encryption password untuk koneksi ke database, maka kita perlu mengenkripsi password database terlebih dahulu. Pada *file* `docker-compose.yml`, password database adalah `semart`, maka kita perlu menjalankan perintah berikut:\n\u003e\n\n```bash\ndocker compose -f docker-compose.yml build \u0026\u0026 docker compose -f docker-compose.yml up\ndocker compose -f docker-compose.yml exec app bash -c \"php bin/console semart:encrypt semart\"\n```\n\nJika Anda menggunakan [Taskfile](https://taskfile.dev), Anda cukup menjalankan perintah:\n\n```bash\ntask encrypt -- semart\n```\n\n\u003e \n\u003e * Abaikan warning atau error yang terjadi\n\u003e \n\u003e * Ubah nilai `DATABASE_PASSWORD` pada file `.env` sesuai dengan hasil perintah di atas\n\u003e \n\u003e *  Restart container\n\u003e\n\u003e * Jalankan perintah berikut:\n\u003e\n\n```bash\ndocker compose -f docker-compose.yml exec app bash -c \"php bin/console cache:clear\"\ndocker compose -f docker-compose.yml exec app bash -c \"chmod 777 -R var\"\ndocker compose -f docker-compose.yml exec app bash -c \"php bin/console doctrine:database:create --no-interaction\"\ndocker compose -f docker-compose.yml exec app bash -c \"php bin/console doctrine:schema:update --force --no-interaction\"\ndocker compose -f docker-compose.yml exec app bash -c \"php bin/console doctrine:fixtures:load --no-interaction\"\ndocker compose -f docker-compose.yml exec app bash -c \"php bin/console assets:install\"\n```\n\nJika Anda menggunakan [Taskfile](https://taskfile.dev), Anda cukup menjalankan perintah:\n\n```bash\ntask install\n```\n\n\u003e \n\u003e * Swagger berjalan pada alamat `http://localhost:9876/api/doc` dengan username `admin` dan password `admin`\n\u003e\n\u003e * Admin berjalan pada alamat `http://localhost:9876/admin` dengan username `admin` dan password `admin` sama seperti pada Swagger\n\u003e\n\u003e * Adminer berjalan pada alamat `http://localhost:6789` dengan host `db`, username `root` dan password `semart`\n\u003e\n\n## Cara Penggunaan\n\n#### Buat Folder `Todo/Model` pada `app`\n\n```bash\ncd \u003cyour_installation_dir\u003e \u0026\u0026 mkdir -p app/Todo/Model\n```\n\n#### Buat Interface `TodoInterface` pada folder `Todo/Model`\n\nModel harus extends `KejawenLab\\ApiSkeleton\\Entity\\EntityInterface` interface\n\n```php\n\u003c?php\n\ndeclare(strict_types=1);\n\nnamespace KejawenLab\\Application\\Todo\\Model;\n\nuse KejawenLab\\ApiSkeleton\\Entity\\EntityInterface;\n\n/**\n * @author Muhamad Surya Iksanudin\u003csurya.iksanudin@gmail.com\u003e\n */\ninterface TodoInterface extends EntityInterface\n{\n    public function getId(): ?string;\n\n    public function getTask(): ?string;\n\n    public function isDone(): bool;\n}\n\n```\n\n#### Buat Entity pada folder `app/Entity`\n\nEntity harus implement `KejawenLab\\Application\\Todo\\Model\\TodoInterface`. \n\nKamu dapat merujuk pada dokumentasi resmi tentang [Mapping Entity](https://symfony.com/doc/current/doctrine.html#creating-an-entity-class), namun sangat tidak disarankan menggunakan Symfony Maker untuk membuat entity pada SemartApiSkeleton\n\n```php\n\u003c?php\n\ndeclare(strict_types=1);\n\nnamespace KejawenLab\\Application\\Entity;\n\nuse Doctrine\\ORM\\Mapping as ORM;\nuse Gedmo\\Blameable\\Traits\\BlameableEntity;\nuse Gedmo\\Mapping\\Annotation as Gedmo;\nuse Gedmo\\SoftDeleteable\\Traits\\SoftDeleteableEntity;\nuse Gedmo\\Timestampable\\Traits\\TimestampableEntity;\nuse KejawenLab\\Application\\Repository\\TodoRepository;\nuse KejawenLab\\Application\\Todo\\Model\\TodoInterface;\nuse KejawenLab\\ApiSkeleton\\Util\\StringUtil;\nuse OpenApi\\Attributes as OA;\nuse Ramsey\\Uuid\\Doctrine\\UuidGenerator;\nuse Ramsey\\Uuid\\UuidInterface;\nuse Symfony\\Component\\Serializer\\Annotation\\Groups;\nuse Symfony\\Component\\Validator\\Constraints as Assert;\n\n#[Gedmo\\SoftDeleteable(fieldName: 'deletedAt')]\n#[ORM\\Entity(repositoryClass: TodoRepository::class)]\n#[ORM\\Table(name: 'todos')]\nclass Todo implements TodoInterface\n{\n    use BlameableEntity;\n    use SoftDeleteableEntity;\n    use TimestampableEntity;\n\n    #[Groups(groups: ['read'])]\n    #[OA\\Property(type: 'string')]\n    #[ORM\\Id]\n    #[ORM\\Column(type: 'uuid', unique: true)]\n    #[ORM\\CustomIdGenerator(class: UuidGenerator::class)]\n    #[ORM\\GeneratedValue(strategy: 'CUSTOM')]\n    private UuidInterface $id;\n\n    #[Assert\\Length(max: 255)]\n    #[Assert\\NotBlank]\n    #[Groups(groups: ['read'])]\n    #[ORM\\Column(type: 'string', length: 255)]\n    private ?string $task;\n\n    #[Groups(groups: ['read'])]\n    #[ORM\\Column(type: 'boolean')]\n    private bool $done;\n    \n    public function __construct()\n    {\n        $this-\u003etask = null;\n        $this-\u003edone = false;\n    }\n\n    public function getId(): ?string\n    {\n        return (string) $this-\u003eid;\n    }\n\n    public function getTask(): ?string\n    {\n        return $this-\u003etask;\n    }\n\n    public function setTask(string $task): void\n    {\n        $this-\u003etask = StringUtil::title($task);\n    }\n\n    public function isDone(): bool\n    {\n        return $this-\u003edone;\n    }\n\n    public function setDone(bool $done): void\n    {\n        $this-\u003edone = $done;\n    }\n\n    public function getNullOrString(): ?string\n    {\n        return $this-\u003egetTask();\n    }\n}\n\n```\n\nClass `KejawenLab\\Application\\Repository\\TodoRepository` untuk sekarang belum ada, namun jangan khawatir, SemartApiSkeleton akan mengenerate class tersebut nanti.\n\n#### Daftarkan sebagai auditable\n\nBuka file `config/packages/dh_auditor.yaml` dan daftarkan entity sebagai berikut:\n\n```yaml\ndh_auditor:\n    providers:\n        doctrine:\n            entities:\n                ...\n                KejawenLab\\Application\\Entity\\Todo: ~\n```\n\n#### Generate Controller, Form, Repository, Serivce, Register Menu, Template, dan Api Documentation\n\n```bash\ndocker compose -f docker-compose.yml exec app bash -c \"php bin/console semart:generate Todo\"\ndocker compose -f docker-compose.yml exec app bash -c \"php bin/console doctrine:schema:update --force --no-interaction\"\n```\n\nJika Anda menggunakan [Taskfile](https://taskfile.dev), Anda cukup menjalankan perintah:\n\n```bash\ntask generate -- Todo\n```\n\n![Generate Command](doc/assets/generate-command.png)\n\nSetelah menjalankan perintah di atas maka susunan folder `Todo/Model` akan menjadi seperti berikut:\n\n![After Generate](doc/assets/after-generate.png)\n\nDan jika kamu login ke Semart Api Skeleton maka akan muncul menu `Todo` pada sidebar sebagai berikut:\n\n![After Generate](doc/assets/side-menu-todo.png)\n\nDan ketika membuka menu `Menu` maka record `Todo` pun akan muncul sebagai berikut:\n\n![Menu](doc/assets/menu-todo.png)\n\nDan pastinya kamu juga bisa set permission untuk `Todo` pada menu Hak Akses (`Group` -\u003e `Lihat` -\u003e `Hak Akses`) sebagai berikut:\n\n![Todo Permission](doc/assets/permission-todo.png)\n\nDan jika kamu mengakses halaman Api Documentation maka akan muncul section `Todo` sebagai berikut:\n\n![Api Doc](doc/assets/api-todo.png)\n\nSangat mudah sekali bukan? Selanjutnya kamu harus restart dulu docker-nya agar class-class yang tadi digenerate dan didaftarkan sebagai service. Hal ini perlu dilakukan karena kita menggunakan swoole. \n\n#### Update translation\n\nKetika kamu mengetik menu `Todo` pada sidebar, maka akan muncul tampilan sebagai berikut:\n\n![Todo List](doc/assets/todo-page.png)\n\nTerdapat beberapa text yang aneh? Santai, kamu cukup buka file `translations/pages.id.yaml` dan tambahkan baris berikut:\n\n```yaml\n        todo:\n            saved: 'Todo berhasil disimpan'\n            deleted: 'Todo berhasil dihapus'\n            not_found: 'Todo tidak ditemukan'\n            list: 'Daftar Todo'\n            add: 'Tambah Todo'\n            edit: 'Ubah Todo'\n            view: 'Detil Todo'\n```\n\nSelanjut, kamu juga perlu mengubah translasi pada file `translations/tables.id.yaml` sebagai berikut:\n\n```yaml\n\n            todo:\n                task: 'Tugas'\n                done: 'Selesai?'\n```\n\nSelanjutnya, kamu juga perlu mengubah translasi pada file `translations/forms.id.yaml` dan tambahkan baris berikut:\n\n```yaml\n            todo:\n                task: 'Tugas'\n                done: 'Selesai?'\n```\n\nKetika kamu berusaha menambahkan task, maka akan kamu harus mengeklik check box `done`, untuk memodifikasi itu, kamu harus mengubah definisi form (akan dibahas selanjutnya).\n\nJangan lupa untuk merestart docker untuk mendapatkan perubahan.\n\nUntuk lebih jelas tentang translasi pada Symfony, kamu dapat membaca dokumentasi resmi tentang [Symfony Translation](https://symfony.com/doc/current/translation.html)\n\n#### Update form type\n\nSecara default, semua field yang ada pada form adalah `required` sehingga kita wajib mengisinya. Untuk mengubahnya, ubah config file `Form/TodoType` pada fungsi `buildForm` sebagai berikut:\n\n```php\n    public function buildForm(FormBuilderInterface $builder, array $options)\n    {\n        $builder-\u003eadd('task', null, [\n            'required' =\u003e true,\n            'label' =\u003e 'sas.form.field.todo.task',\n        ]);\n        $builder-\u003eadd('done', null, [\n            'required' =\u003e false,\n            'label' =\u003e 'sas.form.field.todo.done',\n        ]);\n    }\n```\n\nUntuk lebih jelas tentang Symfony Form, kamu dapat membaca dokumentasi resmi tentang [Symfony Form](https://symfony.com/doc/current/forms.html)\n\nJangan lupa untuk merestart docker untuk mendapatkan perubahan.\n\nPerubahan ini akan berlaku pada halaman Admin maupun Rest Api.\n\n#### Mengaktifkan fungsi pencarian\n\nSecara default, SemartApiSkeleton telah menyiapkan class untuk menghandle kustomasi query, namun SemartApiSkeleton tidak memberikan logic apapun pada class tersebut. Kamu sendiri yang perlu memberikut logic pada class tersebut.\n\nSebagai contoh, kita akan coba mengaktifkan fungsi pencarian Todo berdasarkan field `task`, maka kita mengubah file `Todo/Query/SearchQueryExtension` pada fungsi `apply` sebagai berikut:\n\n```php\n    public function apply(QueryBuilder $queryBuilder, Request $request): void\n    {\n        $query = $request-\u003equery-\u003eget('q');\n        if (!$query) {\n            return;\n        }\n\n        $queryBuilder-\u003eandWhere(\n            $queryBuilder-\u003eexpr()-\u003elike(\n                sprintf('UPPER(%s.task)', $this-\u003ealiasHelper-\u003efindAlias('root')),\n                $queryBuilder-\u003eexpr()-\u003eliteral(sprintf('%%%s%%', StringUtil::uppercase($query)))\n            )\n        );\n    }\n```\n\nSemartApiSkeleton menggunakan [Doctrine Query Builder](https://www.doctrine-project.org/projects/doctrine-orm/en/2.9/reference/query-builder.html) untuk melakukan kustomasi query pada query extension.\n\nJangan lupa untuk merestart docker untuk mendapatkan perubahan.\n\n#### Update Template\n\nSecara default, SemartApiSkeleton akan mengubah `bool` menjadi `string` (direpresentasikan dengan `0` dan `1`) seperti pada daftar todo berikut:\n\n![Todo List](doc/assets/todo-template.png)\n\nKita dapat mengubahnya melalui file `templates/todo/all.html.twig` sebagai berikut:\n\n```twig\n{% for property in properties %}\n    {% if 'id' != property.name %}\n        \u003ctr\u003e\n            \u003ctd style=\"width: 149px;\"\u003e{{ ('sas.table.column.' ~ context ~ '.' ~ property.name) | trans({}, 'tables') }}\u003c/td\u003e\n            \u003ctd style=\"width: 7px;\"\u003e:\u003c/td\u003e\n            {% if 'done' == property.name %}\n                \u003ctd\u003e{% if todo.done %}Selesai{% else %}Belum Selesai{% endif %}\u003c/td\u003e\n            {% else %}\n                \u003ctd\u003e{{ semart_print(attribute(data, property.name)) }}\u003c/td\u003e\n            {% endif %}\n        \u003c/tr\u003e\n    {% endif %}\n{% endfor %}\n```\n\nSelain itu, kita juga perlu mengubah file `templates/todo/view.html.twig` sebagai berikut:\n\n```twig\n{% for property in properties %}\n    {% if 'id' != property.name %}\n        \u003ctr\u003e\n            \u003ctd style=\"width: 149px;\"\u003e{{ ('sas.table.column.' ~ context ~ '.' ~ property.name) | trans({}, 'tables') }}\u003c/td\u003e\n            \u003ctd style=\"width: 7px;\"\u003e:\u003c/td\u003e\n            {% if 'done' == property.name %}\n                \u003ctd\u003e{% if data.done %}Selesai{% else %}Belum Selesai{% endif %}\u003c/td\u003e\n            {% else %}\n                \u003ctd\u003e{{ semart_print(attribute(data, property.name)) }}\u003c/td\u003e\n            {% endif %}\n        \u003c/tr\u003e\n    {% endif %}\n{% endfor %}\n```\n\nUntuk lebih jelas tentang Twig Template, kamu dapat membaca dokumentasi resmi [Twig Template](https://twig.symfony.com)\n\nJangan lupa untuk merestart docker untuk mendapatkan perubahan.\n\n## Fitur\n\n\u003e\n\u003e * RESTful Api Generator\n\u003e\n\u003e * Admin Generator\n\u003e\n\u003e * Api Documentation\n\u003e\n\u003e * Sandbox\n\u003e\n\u003e * JWT Authentication\n\u003e\n\u003e * Rate Limiter\n\u003e\n\u003e * Single Sign In\n\u003e\n\u003e * Query Extension\n\u003e\n\u003e * Soft Deletable\n\u003e\n\u003e * Audit Trail\n\u003e\n\u003e * User Management\n\u003e\n\u003e * Profile Management\n\u003e\n\u003e * Group Management\n\u003e\n\u003e * Menu Management\n\u003e\n\u003e * Permission Management\n\u003e\n\u003e * Setting Management\n\u003e\n\u003e * Cronjob Management\n\u003e\n\u003e * Cache Management\n\u003e\n\u003e * Media Management\n\u003e\n\u003e * Public \u0026 Private Media Support\n\u003e\n\u003e * Public \u0026 Private Api Support\n\u003e\n\u003e * Housekeeping\n\u003e\n\u003e * Password History\n\u003e\n\u003e * Api Client/Consumer Management\n\u003e\n\u003e * Health Check\n\u003e\n\u003e * Export to CSV\n\u003e\n\n## Dokumentasi\n\n#### Dasar\n\n- [Penggunaan Dasar](doc/generator.md)\n\n- [Sandbox](doc/sandbox.md)\n\n- [Authentikasi](doc/auth.md)\n\n- [*Form*](doc/form.md)\n\n- [Pencarian](doc/search.md)\n\n- [Pengaturan *Permission*](doc/permission.md)\n\n- [Manajemen Cronjob](doc/cron.md)\n\n- [Menu](doc/menu.md)\n\n- [Api Publik](doc/public.md)\n\n#### Lanjutan\n\n- [Handel Kompleks Query](doc/query_extension.md)\n\n- [Menambah Tipe *User* Baru](doc/user.md)\n\n## Digunakan Oleh\n\n\u003ctable\u003e\n  \u003ctbody width=\"100%\"\u003e\n    \u003ctr valign=\"top\"\u003e\n      \u003ctd width=\"50%\" align=\"center\" style=\"padding-bottom: 17px\"\u003e\n        \u003cspan\u003eKementerian Pariwisata\u003c/span\u003e\u003cbr\u003e\n        \u003cspan style=\"font-size: small\"\u003e(checked: 8-7-2021)\u003c/span\u003e\u003cbr\u003e\u003cbr\u003e \n        \u003cimg height=\"77px\" src=\"./doc/assets/kemenpar.png\"\u003e\n      \u003c/td\u003e\n      \u003ctd width=\"50%\" align=\"center\"\u003e\n        \u003cspan\u003ePemprov DKI Jakarta\u003c/span\u003e\u003cbr\u003e\n        \u003cspan style=\"font-size: small\"\u003e(checked: 8-7-2021)\u003c/span\u003e\u003cbr\u003e\u003cbr\u003e \n        \u003cimg height=\"77px\" src=\"./doc/assets/dki.png\"\u003e\n      \u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr valign=\"top\"\u003e\n      \u003ctd width=\"50%\" align=\"center\" style=\"padding-bottom: 17px\"\u003e\n        \u003cspan\u003eKementerian Kesehatan\u003c/span\u003e\u003cbr\u003e\n        \u003cspan style=\"font-size: small\"\u003e(checked: 17-11-2021)\u003c/span\u003e\u003cbr\u003e\u003cbr\u003e \n        \u003cimg height=\"77px\" src=\"./doc/assets/kemkes.jpeg\"\u003e\n      \u003c/td\u003e\n      \u003ctd width=\"50%\" align=\"center\"\u003e\n        \u003cspan\u003eDirektorat Jenderal Imigrasi\u003c/span\u003e\u003cbr\u003e\n        \u003cspan style=\"font-size: small\"\u003e(checked: 04-01-2022)\u003c/span\u003e\u003cbr\u003e\u003cbr\u003e \n        \u003cimg height=\"77px\" src=\"./doc/assets/imigrasi.png\"\u003e\n      \u003c/td\u003e\n    \u003c/tr\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\n## Copyright\n\nSemart Api Skeleton dikembangkan dan dimaintain oleh [KejawenLab](https://github.com/KejawenLab)\n\n## Lisensi\n\nLisensi dari Semart Api Skeleton adalah [MIT License](LICENSE) namun proyek yang dibangun menyeseuaikan dengan kebijakan masing-masing\n\n## Screenshot\n\n#### Halaman Admin\n\n![Admin](doc/assets/admin.png)\n\n#### Api Doc\n![Api Doc](doc/assets/full.png)\n\n#### Sandbox\n![Sandbox](doc/assets/sandbox.png)\n\n#### Cronjob Management\n![Cronjob](doc/assets/cron.png)\n\n#### Setting Management\n![Setting](doc/assets/setting.png)\n\n#### Media Management\n![Media](doc/assets/media.png)\n\n#### Group Management\n![Group](doc/assets/group.png)\n\n#### Menu Management\n![Menu](doc/assets/menu.png)\n\n#### User Management\n![User](doc/assets/user.png)\n\n#### Profile Management\n![Profile](doc/assets/profile.png)\n\n#### Client/Api Consumer Management\n![Consumer](doc/assets/consumer.png)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FKejawenLab%2FSemartApiSkeleton","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FKejawenLab%2FSemartApiSkeleton","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FKejawenLab%2FSemartApiSkeleton/lists"}