{"id":17998693,"url":"https://github.com/otaaaviio/disc-laravel","last_synced_at":"2025-03-26T05:30:53.624Z","repository":{"id":243931438,"uuid":"813348903","full_name":"otaaaviio/disc-laravel","owner":"otaaaviio","description":"A simple discord clone with laravel reverb","archived":false,"fork":false,"pushed_at":"2024-06-27T20:38:20.000Z","size":301,"stargazers_count":9,"open_issues_count":0,"forks_count":1,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-03-21T06:41:40.108Z","etag":null,"topics":["laravel","postgresql","reverb","vue"],"latest_commit_sha":null,"homepage":"","language":"PHP","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/otaaaviio.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":"2024-06-10T23:07:28.000Z","updated_at":"2024-09-25T04:43:11.000Z","dependencies_parsed_at":"2024-06-27T23:27:11.937Z","dependency_job_id":null,"html_url":"https://github.com/otaaaviio/disc-laravel","commit_stats":null,"previous_names":["otaaaviio/disc-laravel"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/otaaaviio%2Fdisc-laravel","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/otaaaviio%2Fdisc-laravel/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/otaaaviio%2Fdisc-laravel/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/otaaaviio%2Fdisc-laravel/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/otaaaviio","download_url":"https://codeload.github.com/otaaaviio/disc-laravel/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":245597173,"owners_count":20641859,"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":["laravel","postgresql","reverb","vue"],"created_at":"2024-10-29T21:26:33.108Z","updated_at":"2025-03-26T05:30:53.163Z","avatar_url":"https://github.com/otaaaviio.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Discord Clone\n\n## Table of Contents\n\n- [Introduction](#introduction)\n- [Stack](#stack)\n- [Installation](#installation)\n- [Tests](#tests)\n- [Documentation](#documentation)\n- [Contributing and Examples](#contributing-and-examples)\n- [First time in the project](#first-time-in-the-project)\n- [About implementation](#about-implementation)\n\n## Introduction\n\nThis is a simple discord clone with real time chat, authentication and guilds (servers) with channels system.\nThe objetive of this project is show a websocket example with Laravel Reverb.\nAlso, demonstrate examples of how use Laravel Sanctum and application of the SOLID principles.\n\n## Stack\n\n- [Laravel 11]()\n- [Laravel Reverb](https://reverb.laravel.com/)\n- [Vue](https://vuejs.org/)\n- [PostgreSQL](https://www.postgresql.org/)\n- [Docker](https://www.docker.com/)\n- [Pest](https://pestphp.com/)\n\n## Installation\n\nTo execute this project, you need to have installed Docker in your machine. After that, follow the steps:\n\n1. Clone the repository\n\n```\ngit clone https://github.com/otaaaviio/disc-laravel.git\n```\n\n2. Enter on project folder\n\n```\ncd disc-laravel\n```\n\n3. In src folder, execute the bin for setup:\n\n```bash\n./bin/setup.sh\n```\n\nps: This step should take a while, because the docker will download the images and install the dependencies.\n\n4. Access in your browser the address:\n\n```\nhttp://0.0.0.0:80\n```\n\n5. In .env, you need change this variables for production:\n\n```\nREVERB_APP_ID=\nREVERB_APP_KEY=\nREVERB_APP_SECRET=\n```\n\nFor the next times, you can use this for stop or start the containers:\n\n```bash\n./bin/start.sh\n```\n\n```bash\n./bin/stop.sh\n```\n\n## Tests\n\nThis project contains units and integration tests. Always this branch is pushed, will execute tests in GitHub Actions. Also, to you execute tests, use the command:\n\n```bash\n./vendor/bin/sail test\n```\n\nps: You need run the containers before execute the tests.\n\n## First time in the project\n\nWhen you set up the project with setup.sh, will run seeder with 2 users: \u003cbr\u003e\nAdm user:\n\n```\nemail: adm@admin.com\npassword: password\n```\n\nNormal user:\n\n```\nemail: usr@user.com\npassword: password\n```\n\nWith these credentials, you can access the application in different browsers and experience the real-time chat\nfunctionality.\n\n## Documentation\n\nI used the [scramble](https://scramble.dedoc.co/) for the api documentation. You can see accessing the address:\n\n```\nhttp://0.0.0.0:80/docs/api\n```\n\nIn this documentation, you can see the endpoints, request and response examples.\n\n## About implementation\n\n### Services: \u003cbr\u003e\n\nI used service abstraction, to separate the business logic from the controller and have a better maintenance. \u003cbr\u003e\n\n### Repositories: \u003cbr\u003e\n\nAbout repositories, I don't like use repository pattern in simple laravel projects,\nbecause in majority cases, the eloquent is enough, and we don't change the framework project. \u003cbr\u003e\nIn larger projects, where there might be a need to change the framework, the repository pattern is a good choice.\n\n### Websockets: \u003cbr\u003e\n\nI used Laravel Reverb to implement the websockets. It's not hard to implement, but debug this should be a little hard if\nyou don't have familiarity with websockets. \u003cbr\u003e\nEven though it's a relatively new technology, it's a good choice to learn and apply in your personal or professional\nprojects.\n\n### Jobs: \u003cbr\u003e\n\nI used jobs to send the mail to new users, with welcome message. And use a different connection to send the mail. \u003cbr\u003e\n\n### Tests: \u003cbr\u003e\n\nI used Pest for tests. It's a simple and clean test framework. I like it because it's easy to read and write tests. \u003cbr\u003e\n\n### Docker: \u003cbr\u003e\n\nI used the Laravel Sail with some modifications for this project, like change the images and add vite container. \u003cbr\u003e\n\n### FrontEnd: \u003cbr\u003e\n\nI used Vue for frontend, just for my familiarity with this framework.\nAnd I focus in the backend, so the frontend is simple and functional.\n\n## Contributing and Examples\n\nYou can fork this project and make a pull request with your changes. I will be happy to review and accept your\ncontribution.\nIf you follow the current project pattern, everything will work fine. :D\n\u003cbr\u003e\nA example to you follow, with this you can maintain the project clean and organized, with easy maintenance:\n\nResource to lead with responses to client:\n\n```php\nclass ModelResource extends JsonResource\n{\n    public function toArray(Request $request): array\n    {\n        return [\n        // here you can edit what you want to return\n        ];\n    }\n}\n```\n\nRequest to validate the request data:\n\n```php\nclass ModelRequest extends FormRequest\n{\n    public function rules(): array\n    {\n        return [\n            // some rules you want validated\n        ];\n    }\n}\n```\n\nExceptions to lead with errors in a clean way and eay to understand:\n\n```php\nclass ModelException extends Exception\n{\n    public function __construct($message = '', $code = StatusCode::HTTP_INTERNAL_SERVER_ERROR, ?Throwable $previous = null)\n    {\n        parent::__construct($message, $code, $previous);\n    }\n\n    public static function someError(): self\n    {\n        return new self(\n            'Some error message here',\n            StatusCode::HTTP_ERROR\n        );\n    }\n\n    public function render($request): JsonResponse\n    {\n        return response()-\u003ejson([\n            'message' =\u003e $this-\u003egetMessage(),\n        ], $this-\u003egetCode());\n    }\n}\n```\n\nController to receive request and return answer to client:\n\n```php\npublic function store(ModelRequest $request)\n{\n    // this will clean fields that are not in the rules\n    $data = $this-\u003evalidated();\n\n    //here you process the request, within show the business logic \n    $modelResource = $this-\u003eservice-\u003ecreate($data);\n\n    // here you can style the response and return \n    return response()-\u003ejson([\n    'message' =\u003e 'Some message here',\n    'model' =\u003e $modelResource\n    ], StatusCode::HTTP_CREATED);\n}\n```\n\nService to lead with business logic and return the resource to controller:\n\n```php\npublic function create(array $data)\n{\n    // here you process the data and return the resource and treat errors with custom exceptions\n    \n    if($error) {\n        // this is useful to maintain the handling of errors in the same place\n        throw CustomException::someError();\n    }\n    \n    return ModelResource::make($model);\n}\n```\n\nFor Websockets, you can add new events to project, like:\n\n```php\nclass SomeEvent implements ShouldBroadcast\n{\n    use Dispatchable, InteractsWithSockets, SerializesModels;\n\n    public function __construct(\n        public Model $model\n    ) {\n        //\n    }\n\n    // channel where the event will be broadcast\n    public function broadcastOn(): Channel\n    {\n        return new Channel('channel.'.$this-\u003emodel-\u003eid);\n    }\n\n    // data to send in event\n    public function broadcastWith(): array\n    {\n        return [\n            'model' =\u003e $this-\u003emodel\n        ];\n    }\n\n    // person event name to access in client side\n    public function broadcastAs(): string\n    {\n        return 'some-event';\n    }\n}\n```\nWith websockets you can add real-time features to your project, like chat, notifications and others.\nFor more infos, you can see the [Laravel Documentation](https://laravel.com/docs)\n\n## Contact\n\nIf you have any questions, you can contact me by email or linkedin:\n\n```\noglamberty@inf.ufsm.br\n\nhttps://www.linkedin.com/in/otaaaviio/\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fotaaaviio%2Fdisc-laravel","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fotaaaviio%2Fdisc-laravel","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fotaaaviio%2Fdisc-laravel/lists"}