{"id":26233582,"url":"https://github.com/therealsatria/linqwebapi","last_synced_at":"2026-04-13T10:32:27.541Z","repository":{"id":279233909,"uuid":"938143619","full_name":"therealsatria/LINQwebAPI","owner":"therealsatria","description":"This project is an example implementation of a Web API using ASP.NET Core 8 with LINQ as the Object-Relational Mapper (ORM). The use case is the management of product data through the Product table.","archived":false,"fork":false,"pushed_at":"2025-03-12T17:17:54.000Z","size":23947,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-03-12T18:27:41.442Z","etag":null,"topics":["api-rest","asp-net-core","crud","dependency-injection","dotnet-core","dto-pattern","efcore","sqlite"],"latest_commit_sha":null,"homepage":"","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/therealsatria.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"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":"2025-02-24T13:45:53.000Z","updated_at":"2025-03-12T17:18:02.000Z","dependencies_parsed_at":null,"dependency_job_id":"b427b9d3-db53-4a55-be74-5fd8e069382b","html_url":"https://github.com/therealsatria/LINQwebAPI","commit_stats":null,"previous_names":["therealsatria/linqwebapi"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/therealsatria%2FLINQwebAPI","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/therealsatria%2FLINQwebAPI/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/therealsatria%2FLINQwebAPI/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/therealsatria%2FLINQwebAPI/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/therealsatria","download_url":"https://codeload.github.com/therealsatria/LINQwebAPI/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243318768,"owners_count":20272144,"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":["api-rest","asp-net-core","crud","dependency-injection","dotnet-core","dto-pattern","efcore","sqlite"],"created_at":"2025-03-13T01:16:31.678Z","updated_at":"2025-12-26T11:01:34.660Z","avatar_url":"https://github.com/therealsatria.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Product Web API with ASP.NET Core 8 and LINQ\n\nThis project is an example implementation of a Web API using ASP.NET Core 8 with LINQ as the Object-Relational Mapper (ORM). The use case is the management of product data through the `Product` table.\n\n## Features\n\n* **Product CRUD (Create, Read, Update, Delete):**\n    * Add new products.\n    * View a list of all products.\n    * View product details by ID.\n    * Modify product data.\n    * Delete products.\n* **LINQ for Data Access:**\n    * Implementation of database operations using LINQ for ease and flexibility.\n* **RESTful API Architecture:**\n    * API design follows RESTful principles for ease of use and scalability.\n* **In-Memory or SQL Server Database:**\n    * The project can be configured to use an in-memory database for development or SQL Server for production.\n\n## Technologies Used\n\n* **ASP.NET Core 8:** Web framework for building APIs.\n* **.NET 8:** Development platform.\n* **Entity Framework Core:** ORM for database access.\n* **LINQ (Language Integrated Query):** Integrated query language for data manipulation.\n* **SQL Server (optional):** Relational database.\n* **Swagger/OpenAPI:** API documentation.\n\n## Setup\n\n1.  **Install .NET 8 SDK:**\n    * Download and install the .NET 8 SDK from the official Microsoft website.\n2.  **Install Visual Studio or Visual Studio Code:**\n    * Use Visual Studio or Visual Studio Code as your IDE.\n3.  **Install SQL Server (optional):**\n    * If you want to use SQL Server, install and configure SQL Server on your computer.\n\n## Configuration\n\n1.  **Database Configuration:**\n    * Open the `appsettings.json` file.\n    * Change the connection string according to your database configuration.\n        * To use an in-memory database, leave the default configuration.\n        * To use SQL Server, replace the connection string with a connection to your SQL Server database.\n2.  **Database Migration:**\n    * Open a terminal in the project directory.\n    * Run the following commands to create migrations and update the database:\n        * `dotnet ef migrations add InitialCreate`\n        * `dotnet ef database update`\n\n## How to Run the Application\n\n1.  **Open the project in Visual Studio or Visual Studio Code.**\n2.  **Run the application by pressing the \"Run\" button or using the `dotnet run` command in the terminal.**\n3.  **Open a browser and access the API URL (e.g., `https://localhost:5001/swagger`) to view the Swagger documentation.**\n4.  **Use Postman or a similar tool to test the API endpoints.**\n\n## API Endpoints\n\n### Authentication\n* `POST /api/Auth/login` - Login dan mendapatkan token JWT\n* `POST /api/Auth/register` - Registrasi pengguna baru\n* `GET /api/Auth/me` - Mendapatkan informasi user yang sedang login\n\n### Products\n* `GET /api/Products` - Mendapatkan daftar semua produk\n* `GET /api/Products/{id}` - Mendapatkan detail produk berdasarkan ID\n* `POST /api/Products` - Menambahkan produk baru (Auth)\n* `PUT /api/Products/{id}` - Mengubah data produk (Auth)\n* `DELETE /api/Products/{id}` - Menghapus produk (Auth)\n\n### Categories\n* `GET /api/Categories` - Mendapatkan daftar semua kategori\n* `GET /api/Categories/{id}` - Mendapatkan detail kategori berdasarkan ID\n* `POST /api/Categories` - Menambahkan kategori baru (Admin only)\n* `PUT /api/Categories/{id}` - Mengubah data kategori (Admin only)\n* `DELETE /api/Categories/{id}` - Menghapus kategori (Admin only)\n\n### Suppliers\n* `GET /api/Suppliers` - Mendapatkan daftar semua supplier\n* `GET /api/Suppliers/{id}` - Mendapatkan detail supplier berdasarkan ID\n* `POST /api/Suppliers` - Menambahkan supplier baru (Auth)\n* `PUT /api/Suppliers/{id}` - Mengubah data supplier (Auth)\n* `DELETE /api/Suppliers/{id}` - Menghapus supplier (Auth)\n\n### Inventory\n* `GET /api/Inventory` - Mendapatkan daftar semua inventaris\n* `GET /api/Inventory/{id}` - Mendapatkan detail inventaris berdasarkan ID\n* `POST /api/Inventory` - Menambahkan inventaris baru (Auth)\n* `PUT /api/Inventory/{id}` - Mengubah data inventaris (Auth)\n* `DELETE /api/Inventory/{id}` - Menghapus inventaris (Auth)\n\n### Orders\n* `GET /api/Orders` - Mendapatkan daftar semua pesanan\n* `GET /api/Orders/{id}` - Mendapatkan detail pesanan berdasarkan ID\n* `POST /api/Orders` - Menambahkan pesanan baru (Auth)\n* `PUT /api/Orders/{id}` - Mengubah data pesanan (Auth)\n* `DELETE /api/Orders/{id}` - Menghapus pesanan (Auth)\n\n### OrderDetails\n* `GET /api/OrderDetails` - Mendapatkan daftar semua detail pesanan\n* `GET /api/OrderDetails/{id}` - Mendapatkan detail pesanan berdasarkan ID\n* `POST /api/OrderDetails` - Menambahkan detail pesanan baru (Auth)\n* `PUT /api/OrderDetails/{id}` - Mengubah data detail pesanan (Auth)\n* `DELETE /api/OrderDetails/{id}` - Menghapus detail pesanan (Auth)\n\n### Customers\n* `GET /api/Customers` - Mendapatkan daftar semua pelanggan\n* `GET /api/Customers/{id}` - Mendapatkan detail pelanggan berdasarkan ID\n* `POST /api/Customers` - Menambahkan pelanggan baru (Auth)\n* `PUT /api/Customers/{id}` - Mengubah data pelanggan (Auth)\n* `DELETE /api/Customers/{id}` - Menghapus pelanggan (Auth)\n\n### Reports\n* `GET /api/Report/products-by-category` - Laporan produk berdasarkan kategori\n* `GET /api/Report/products-by-category/{categoryId}` - Laporan produk untuk kategori tertentu\n* `GET /api/Report/purchase-details` - Laporan detail pembelian untuk semua pesanan\n* `GET /api/Report/purchase-details/{orderId}` - Laporan detail pembelian untuk pesanan tertentu\n* `GET /api/Report/inventory-value` - Laporan nilai inventaris (Auth)\n* `GET /api/Report/stock-history` - Laporan riwayat perubahan stok (Auth)\n* `GET /api/Report/stock-history/product/{productId}` - Laporan riwayat perubahan stok untuk produk tertentu (Auth)\n\n## Usage Examples\n\n* **Login dan Mendapatkan Token:**\n    ```http\n    POST /api/Auth/login\n    Content-Type: application/json\n\n    {\n        \"username\": \"admin\",\n        \"password\": \"Admin123!\"\n    }\n    ```\n\n* **Menambahkan Produk Baru:**\n    ```http\n    POST /api/Products\n    Authorization: Bearer your_token_here\n    Content-Type: application/json\n\n    {\n        \"name\": \"Laptop XYZ\",\n        \"description\": \"High-specification laptop\",\n        \"price\": 12000000,\n        \"categoryId\": \"c8ad5706-e54c-4c23-b5d8-c22db2984193\",\n        \"supplierId\": \"a67c9d1e-25a8-4f44-b73e-f536b8bce410\"\n    }\n    ```\n\n* **Mendapatkan Daftar Produk:**\n    ```http\n    GET /api/products\n    ```\n\n* **Membuat Pesanan Baru:**\n    ```http\n    POST /api/Orders\n    Authorization: Bearer your_token_here\n    Content-Type: application/json\n\n    {\n        \"customerId\": \"f1b2c3d4-e5f6-7a8b-9c0d-1e2f3a4b5c6d\",\n        \"orderDetails\": [\n            {\n                \"productId\": \"a1b2c3d4-e5f6-7a8b-9c0d-1e2f3a4b5c6d\",\n                \"quantity\": 2,\n                \"unitPrice\": 1200000\n            },\n            {\n                \"productId\": \"b1b2c3d4-e5f6-7a8b-9c0d-1e2f3a4b5c6d\",\n                \"quantity\": 1,\n                \"unitPrice\": 500000\n            }\n        ]\n    }\n    ```\n\n* **Mendapatkan Laporan Nilai Inventaris:**\n    ```http\n    GET /api/Report/inventory-value\n    Authorization: Bearer your_token_here\n    ```\n\n## Contribution\n\nIf you would like to contribute to this project, please fork the repository and submit a pull request.\n\n## License\n\nThis project is licensed under the \\[MIT/Apache 2.0/etc.] license.\n\n## Authentication and Authorization\n\nThe API uses JWT (JSON Web Token) authentication. To access protected endpoints, you need to:\n\n1. Register a new user or use the default admin account:\n   - Default admin credentials:\n     - Username: admin\n     - Email: admin@example.com\n     - Password: Admin123!\n\n2. Obtain a JWT token by logging in:\n```http\nPOST /api/Auth/login\nContent-Type: application/json\n\n{\n    \"username\": \"your_username\",\n    \"password\": \"your_password\"\n}\n```\n\n3. Use the token in subsequent requests:\n   - Add the Authorization header: `Bearer your_token_here`\n   - In Swagger UI: \n     1. Click the \"Authorize\" button (lock icon) at the top right of the page\n     2. In the popup dialog, enter your token in the format: `Bearer your_token_here`\n     3. Click \"Authorize\" and close the dialog\n     4. All subsequent API calls will include your token\n\n### Using Swagger UI with JWT Authentication\n\n1. Start the application and navigate to the Swagger UI (usually at `/swagger`)\n2. First, make a POST request to `/api/Auth/login` with your credentials to get a token\n3. Click the \"Authorize\" button (lock icon) at the top right of the Swagger UI\n4. In the popup dialog, enter your token in the format: `Bearer your_token_here`\n   - Make sure to include the word \"Bearer\" followed by a space before your token\n5. Click \"Authorize\" and close the dialog\n6. Now you can access protected endpoints through the Swagger UI\n7. The lock icons next to endpoints indicate whether they require authentication\n\n### Protected Endpoints\n\n#### Categories\n- Public endpoints (no authentication required):\n  ```http\n  GET /api/Category\n  GET /api/Category/{id}\n  ```\n\n- Admin-only endpoints (requires admin role):\n  ```http\n  POST /api/Category\n  PUT /api/Category/{id}\n  DELETE /api/Category/{id}\n  ```\n\n### User Roles\n- **User**: Basic authenticated user\n  - Can access protected endpoints\n  - Cannot modify system data\n\n- **Admin**: Administrative user\n  - Full access to all endpoints\n  - Can manage categories, products, and other system data\n  - Can view list of users\n\n### Authentication Examples\n\n1. Login and get token:\n```http\nPOST /api/Auth/login\nContent-Type: application/json\n\n{\n    \"username\": \"admin\",\n    \"password\": \"Admin123!\"\n}\n```\n\n2. Create a new category (Admin only):\n```http\nPOST /api/Category\nAuthorization: Bearer your_token_here\nContent-Type: application/json\n\n{\n    \"name\": \"New Category\"\n}\n```\n\n3. Get current user info:\n```http\nGET /api/Auth/me\nAuthorization: Bearer your_token_here\n```\n\n### Error Responses\n\n- **401 Unauthorized**: Missing or invalid token\n- **403 Forbidden**: Valid token but insufficient permissions\n- **400 Bad Request**: Invalid input data\n- **404 Not Found**: Resource not found\n\n# Database Schema dan Relasi\n\n## Model Entitas dan Relasinya\n\n### Products\n* **Id** (Guid, Primary Key)\n* **Name** (string)\n* **Description** (string)\n* **Price** (decimal)\n* **CategoryId** (Guid, Foreign Key)\n* **SupplierId** (Guid, Foreign Key)\n* **CreatedAt** (DateTime)\n* **UpdatedAt** (DateTime)\n\n### Categories\n* **Id** (Guid, Primary Key)\n* **Name** (string)\n* **CreatedAt** (DateTime)\n* **UpdatedAt** (DateTime)\n\n### Inventory\n* **Id** (Guid, Primary Key)\n* **ProductId** (Guid, Foreign Key)\n* **StockQuantity** (int)\n* **LastStockUpdate** (DateTime)\n* **CreatedAt** (DateTime)\n\n### InventoryHistory\n* **Id** (Guid, Primary Key)\n* **InventoryId** (Guid, Foreign Key)\n* **ProductId** (Guid, Foreign Key)\n* **PreviousQuantity** (int)\n* **NewQuantity** (int)\n* **QuantityChange** (int)\n* **ChangeType** (string) - \"Addition\", \"Reduction\", \"Adjustment\"\n* **Notes** (string)\n* **ChangedAt** (DateTime)\n\n### Suppliers\n* **Id** (Guid, Primary Key)\n* **Name** (string)\n* **ContactPerson** (string)\n* **ContactPhone** (string)\n* **CreatedAt** (DateTime)\n* **UpdatedAt** (DateTime)\n\n### Customer\n* **Id** (Guid, Primary Key)\n* **Name** (string)\n* **Email** (string)\n* **Phone** (string)\n* **Address** (string)\n* **CreatedAt** (DateTime)\n* **UpdatedAt** (DateTime)\n\n### Orders\n* **Id** (Guid, Primary Key)\n* **OrderDate** (DateTime)\n* **CustomerId** (Guid, Foreign Key)\n* **TotalAmount** (decimal)\n* **CreatedAt** (DateTime)\n* **UpdatedAt** (DateTime)\n\n### OrderDetails\n* **Id** (Guid, Primary Key)\n* **OrderId** (Guid, Foreign Key)\n* **ProductId** (Guid, Foreign Key)\n* **Quantity** (int)\n* **UnitPrice** (decimal)\n* **CreatedAt** (DateTime)\n* **UpdatedAt** (DateTime)\n\n### User\n* **Id** (Guid, Primary Key)\n* **Username** (string)\n* **Email** (string)\n* **PasswordHash** (string)\n* **Role** (string) - \"User\", \"Admin\"\n* **CreatedAt** (DateTime)\n* **UpdatedAt** (DateTime)\n\n## Relasi Antar Tabel\n\n1. **Products ↔ Categories** (Many-to-One)\n   - Setiap produk memiliki satu kategori\n   - Satu kategori dapat memiliki banyak produk\n\n2. **Products ↔ Suppliers** (Many-to-One)\n   - Setiap produk memiliki satu supplier\n   - Satu supplier dapat memasok banyak produk\n\n3. **Products ↔ Inventory** (One-to-Many)\n   - Setiap produk dapat memiliki beberapa catatan inventaris\n   - Satu catatan inventaris hanya terkait dengan satu produk\n\n4. **Products ↔ OrderDetails** (One-to-Many)\n   - Satu produk dapat berada di banyak detail pesanan\n   - Satu detail pesanan hanya terkait dengan satu produk\n\n5. **Inventory ↔ InventoryHistory** (One-to-Many)\n   - Satu catatan inventaris dapat memiliki banyak riwayat perubahan\n   - Satu riwayat perubahan hanya terkait dengan satu inventaris\n\n6. **Orders ↔ OrderDetails** (One-to-Many)\n   - Satu pesanan dapat terdiri dari banyak detail pesanan\n   - Satu detail pesanan hanya terkait dengan satu pesanan\n\n7. **Customers ↔ Orders** (One-to-Many)\n   - Satu pelanggan dapat membuat banyak pesanan\n   - Satu pesanan hanya terkait dengan satu pelanggan\n\n## Diagram ER\n\n```mermaid\nerDiagram\n    Products {\n        guid Id PK\n        string Name\n        string Description\n        decimal Price\n        guid CategoryId FK\n        guid SupplierId FK\n        datetime CreatedAt\n        datetime UpdatedAt\n    }\n\n    Categories {\n        guid Id PK\n        string Name\n        datetime CreatedAt\n        datetime UpdatedAt\n    }\n\n    Inventory {\n        guid Id PK\n        guid ProductId FK\n        int StockQuantity\n        datetime LastStockUpdate\n        datetime CreatedAt\n    }\n\n    InventoryHistory {\n        guid Id PK\n        guid InventoryId FK\n        guid ProductId FK\n        int PreviousQuantity\n        int NewQuantity\n        int QuantityChange\n        string ChangeType\n        string Notes\n        datetime ChangedAt\n    }\n\n    Suppliers {\n        guid Id PK\n        string Name\n        string ContactPerson\n        string ContactPhone\n        datetime CreatedAt\n        datetime UpdatedAt\n    }\n\n    Customer {\n        guid Id PK\n        string Name\n        string Email\n        string Phone\n        string Address\n        datetime CreatedAt\n        datetime UpdatedAt\n    }\n\n    Orders {\n        guid Id PK\n        datetime OrderDate\n        guid CustomerId FK\n        decimal TotalAmount\n        datetime CreatedAt\n        datetime UpdatedAt\n    }\n\n    OrderDetails {\n        guid Id PK\n        guid OrderId FK\n        guid ProductId FK\n        int Quantity\n        decimal UnitPrice\n        datetime CreatedAt\n        datetime UpdatedAt\n    }\n\n    User {\n        guid Id PK\n        string Username\n        string Email\n        string PasswordHash\n        string Role\n        datetime CreatedAt\n        datetime UpdatedAt\n    }\n\n    Products }|--|| Categories : memiliki\n    Products }|--|| Suppliers : dari\n    Products ||--|{ Inventory : memiliki\n    Inventory ||--|{ InventoryHistory : mencatat\n    InventoryHistory }|--|| Products : berkaitan_dengan\n    Orders ||--|{ OrderDetails : terdiri_dari\n    OrderDetails }|--|| Orders : ada_di\n    OrderDetails }|--|| Products : berisi\n    Orders }|--|| Customer : ditempatkan_oleh\n```\n\n### Keterangan Format Data\n\n* **Guid**: Pengenal unik universal (direpresentasikan sebagai string di API)\n* **DateTime**: Format ISO 8601 (misal: \"2023-03-15T14:30:00Z\")\n* **Decimal**: Angka dengan titik desimal (misal: 1500000.00)\n\n### Struktur Respons API\n\n#### Daftar (List):\n```json\n{\n  \"message\": \"Data retrieved successfully\",\n  \"success\": true,\n  \"data\": [\n    { /* item data */ },\n    { /* item data */ }\n  ]\n}\n```\n\n#### Detail (Single Item):\n```json\n{\n  \"message\": \"Data retrieved successfully\",\n  \"success\": true,\n  \"data\": { /* item data */ }\n}\n```\n\n#### Error:\n```json\n{\n  \"message\": \"Error message\",\n  \"success\": false,\n  \"errors\": [\"Error detail 1\", \"Error detail 2\"]\n}\n```","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftherealsatria%2Flinqwebapi","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftherealsatria%2Flinqwebapi","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftherealsatria%2Flinqwebapi/lists"}